読者です 読者をやめる 読者になる 読者になる

Mae向きなブログ

Mae向きな日記のブログ版。ようやくこちらに移行してきました。

13章分の7章

今日は,『プログラミング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を使って再定義することが出来ませんでした。引き続き考えたいと思います。