import Data.Char
type Bit = Int
bin2int :: [Bit] -> Int
bin2int = foldr (\x y -> x + 2*y) 0
int2bin :: Int -> [Bit]
int2bin 0 = []
int2bin n = n `mod` 2 : int2bin (n `div` 2)
make8 :: [Bit] -> [Bit]
make8 bits = take 8 (bits ++ repeat 0)
encode :: String -> [Bit]
encode = concat . map (add_parity . make8 . int2bin . ord)
chop9 :: [Bit] -> [[Bit]]
chop9 [] = []
chop9 bits = take 9 bits : chop9 (drop 9 bits)
correct :: [Bit] -> Bool
correct = even . parity
check_parity :: [Bit] -> [Bit]
check_parity bits | correct bits = tail bits
| otherwise = error "parity is incorrect -- check_parity"
decode :: [Bit] -> String
decode = map (chr . bin2int . check_parity) . chop9
transmit :: String -> String
transmit = decode . channel . encode
channel :: [Bit] -> [Bit]
channel = tail
parity :: [Bit] -> Bit
parity bits | odd (sum bits) = 1
| otherwise = 0
add_parity :: [Bit] -> [Bit]
add_parity bits = parity bits : bits