+instance Bounded Octet where
+ -- | The octet with the least possible value.
+ minBound =
+ Octet B.Zero B.Zero B.Zero B.Zero B.Zero B.Zero B.Zero B.Zero
+
+ -- | The octet with the greatest possible value.
+ maxBound =
+ Octet B.One B.One B.One B.One B.One B.One B.One B.One
+
+
+instance Enum Octet where
+ -- We're supposed to throw a runtime error if you call (succ
+ -- maxBound), so the fromJust here doesn't introduce any additional
+ -- badness.
+ toEnum = fromJust . octet_from_int
+ fromEnum = octet_to_int
+
+-- | Convert each bit to its integer value, and multiply by the
+-- appropriate power of two. Sum them up, and we should get an integer
+-- between 0 and 255.
+octet_to_int :: Octet -> Int
+octet_to_int x =
+ 128 * (bit_to_int (b1 x)) +
+ 64 * (bit_to_int (b2 x)) +
+ 32 * (bit_to_int (b3 x)) +
+ 16 * (bit_to_int (b4 x)) +
+ 8 * (bit_to_int (b5 x)) +
+ 4 * (bit_to_int (b6 x)) +
+ 2 * (bit_to_int (b7 x)) +
+ 1 * (bit_to_int (b8 x))
+
+
+
+octet_from_int :: Int -> Maybe Octet
+octet_from_int x
+ | (x < 0) || (x > 255) = Nothing
+ | otherwise = Just (Octet a1 a2 a3 a4 a5 a6 a7 a8)
+ where
+ a1 = if (x >= 128) then B.One else B.Zero
+ a2 = if ((x `mod` 128) >= 64) then B.One else B.Zero
+ a3 = if ((x `mod` 64) >= 32) then B.One else B.Zero
+ a4 = if ((x `mod` 32) >= 16) then B.One else B.Zero
+ a5 = if ((x `mod` 16) >= 8) then B.One else B.Zero
+ a6 = if ((x `mod` 8) >= 4) then B.One else B.Zero
+ a7 = if ((x `mod` 4) >= 2) then B.One else B.Zero
+ a8 = if ((x `mod` 2) == 1) then B.One else B.Zero
+
+
+octet_from_string :: String -> Maybe Octet
+octet_from_string s =
+ case (reads s :: [(Int, String)]) of
+ [] -> Nothing
+ x:_ -> octet_from_int (fst x)