今日は,『プログラミングHaskell』の7章を読みました。
第7章 高階関数
第5章では,締めくくりとして,「シーザー暗号」が,本章では,「文字列の変換器」が取り上げられていました。どちらもとても興味深い内容です。しかも,章末の練習問題で,仕様を変更したり拡張したりという問題が含まれており,楽しく取り組むことができました。
以下に,練習問題8と9の自分なりの解答を示します。addparityとcheckparityが,xsを明示しているところが,ちょっと不満です。他の関数と同様に省略した方法で定義したかったのですが,出来ませんでした…。
Haskellerの皆さんのコメントなどがいただければありがたいです。
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 (addparity . make8 . int2bin . ord) chop9 :: [Bit] -> [[Bit]] chop9 [] = [] chop9 bits = take 9 bits: chop9 (drop 9 bits) decode :: [Bit] -> String decode = map (chr . bin2int . checkparity) . chop9 transmit :: String -> String transmit = decode . channel . encode channel :: [Bit] -> [Bit] channel = id . noise addparity :: [Bit] -> [Bit] addparity xs | (odd . sum) xs == True = xs ++ [1] | otherwise = xs ++ [0] checkparity :: [Bit] -> [Bit] checkparity xs | (even . sum) xs == True = (reverse .tail. reverse) xs | otherwise = error "Parity error" noise :: [Bit] -> [Bit] noise xs = concat (map tail (chop9 xs))
実行結果
> transmit "Good evening!"
"#\155\141*** Exception: Parity error
分からなかったところ
練習問題6のcurry関数,uncurry関数,問題7のiterate fをunfoldを使って再定義することが出来ませんでした。引き続き考えたいと思います。