プログラミングHaskell 第7章の練習問題

import Data.Char
type Bit = Int

-- リスト内包表現(list comprehension)[f x | x <- xs, p x]を高階関数で書きなおす
lcomp :: (a -> b) -> (a -> Bool) -> [a] -> [b]
lcomp f p xs = map f (filter p xs)

all' :: (a -> Bool) -> [a] -> Bool
all' p = and . map p

any' :: (a -> Bool) -> [a] -> Bool
any' p = or .map p

takeWhile' :: (a -> Bool) -> [a] -> [a]
takeWhile' _ [] = []
takeWhile' p (x : xs) = if p x then x : (takeWhile' p xs) else []

dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' _ [] = []
dropWhile' p (x : xs) = if p x then dropWhile' p xs else x : xs

map' :: (a -> b) -> [a] -> [b]
map' f = foldr (\x y -> (f x) : y) []

filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x y -> if p x then x : y else y) []

dec2int :: [Int] -> Int
dec2int = foldl (\x y -> 10 * x + y) 0 

curry' :: ((a, b) -> c) -> (a -> b -> c) 
curry' f = \x y -> f (x, y) 

uncurry' :: (a -> b -> c) -> ((a, b) -> c)
uncurry' f = \(x, y) -> f x y

unfold p h t x | p x = []
               | otherwise = h x : unfold p h t (t x)

chop8 :: [Bit] -> [[Bit]]
chop8 = unfold null (take 8) (drop 8)

map'' :: (a -> b) -> [a] -> [b]
map'' f = unfold null (f.head) tail 

iterate' :: (a -> a) -> a -> [a]
iterate' f = unfold (const False) id f 

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 (make8.int2bin.ord)

parity :: [Bit] -> Bit
parity bits = (sum bits) `mod` 2

addParity :: [Bit] -> [Bit]
addParity bits = bits ++ [parity bits]

encode2 :: String -> [Bit]
encode2 = concat.map (addParity.make8.int2bin.ord)

chop9 :: [Bit] -> [[Bit]]
chop9 [] = []
chop9 bits = (take 9 bits) : chop9 (drop 9 bits)

bin2int :: [Bit] -> Int
bin2int = foldr (\x y -> x + 2 * y) 0

check :: [Bit] -> Bool
check bits = if (parity (take x bits)) == last bits then True else False
    where x = (length bits) - 1

decode2 :: [Bit] -> String
decode2 bits = if (and.map check) (chop9 bits) then map (chr.bin2int.take 8) (chop9 bits)
                   else error "parity error"

channel2 :: [Bit] -> [Bit]
channel2 = tail 

transmit2 :: String -> String
transmit2 = decode2.channel2.encode2