Exercise 7.1
foo :: (a -> b) -> (a -> Bool) -> [a] -> [b]
foo f p xs = [f x | x <- xs, p x]
foo' :: (a -> b) -> (a -> Bool) -> [a] -> [b]
foo' f p xs = map f (filter p xs)
-- For example, the following two expressions generate the same list, [1, 9, 25, 49, 81, ...]
sqrodds = [(^2) n | n <- [1..], odd n]
sqrodds' = map (^2) $ filter odd [1..]
Exercise 7.2
all' :: (a -> Bool) -> [a] -> Bool
all' p = foldr (\x y -> p x && y) True
any' :: (a -> Bool) -> [a] -> Bool
any' p = foldr (\x y -> p x || y) False
takeWhile' :: (a -> Bool) -> [a] -> [a]
takeWhile' _ [] = []
takeWhile' p (x:xs) | p x = x : takeWhile' p xs
| otherwise = []
dropWhile' :: (a -> Bool) -> [a] -> [a]
dropWhile' _ [] = []
dropWhile' p (x:xs) | p x = dropWhile' p xs
| otherwise = (x:xs)
Exercise 7.3
map' :: (a -> b) -> [a] -> [b]
map' f = foldr (\x ys -> f x : ys) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x ys -> if p x then x : ys else ys) []
Exercise 7.4
dec2int :: [Int] -> Int
dec2int = foldl (\x y -> x*10 + y) 0
Exercise 7.5
-- Answer: The list passed to compose is invalid because its elements are not all of the same type.
Exercise 7.6
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
Exercise 7.7
unfold :: (a -> Bool) -> (a -> b) -> (a -> a) -> a -> [b]
unfold p h t x | p x = []
| otherwise = h x : unfold p h t (t x)
type Bit = Int
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 (\_ -> False) id f
Exercise 7.8
To encode:
parityBit :: [Bit] -> Bit
parityBit bits = if odd ones then 1 else 0
where ones = sum [b | b <- make8 bits]
make9 :: [Bit] -> [Bit]
make9 bits = (make8 bits) ++ [parityBit bits]
encodePb :: String -> [Bit]
encodePb = concat . map (make9 . int2bin . ord)
To decode:
chop9 :: [Bit] -> [[Bit]]
chop9 = unfold null (take 9) (drop 9) -- where unfold has been defined in Exercise 7.7
dropPb :: [Bit] -> [Bit]
dropPb bits = if last bits == parityBit bits
then take 8 bits
else error "Parity bit error!"
decodePb :: [Bit] -> String
decodePb = (map (chr . bin2int . dropPb)) . chop9
Then:
transmitPb :: String -> String
transmitPb = decodePb . channel . encodePb
where channel = id
Exercise 7.9
transmitPb' :: String -> String
transmitPb' = decodePb . fawltyChannel . encodePb
where fawltyChannel = tail