2007-06-20
■ [Chapter6] Programming with lists (3日目) 
Exercises 6.5
Picture を [ [Bool] ] を使って表すようにしたら、どうなるか、という話。大まかにまとめると
- superimposeChar は、Bool向けに全部書き直しになる('.'や'#'もふくめて)
- superimposeLine は、[Char] 型を [Bool] 型に書き直すだけで十分。関数の枠組は使いまわせる。
- 上記2つの関数が修正されてさえいれば、superimpose は、全く修正せずともOK。
- printPicture を構築する際、Bool型の表現をChar型に変換する必要がある。これは、[ [Bool] ]型のメリットでもあり、デメリットでもある。
- デメリット:変換するための関数を定義する必要がある。
- メリット:変換するための関数を定義すれば、'#'と'.'の2文字に表現を縛られなくても済む。変換関数を書き換えることで、(コンパイラ/インタプリタが許す範囲で)どんな文字でも使うことが出来る。
Exercises 6.6
Picture を時計回りに90°回転させる関数 rotate90 を定義する。先に下ごしらえとして、各Pictureの先頭要素だけを取り出してリスト化する関数 headList と、先頭以外の要素だけを取り出してリスト化する関数 tailList を定義する。
headList :: [ [Char] ] -> [Char]
headList list
| list == [ ] = [ ]
tailList :: [ [Char] ] -> [ [Char] ]
tailList list
| list == [ [ ] ] = [ ]
その上で、rotate90を定義する。
rotate90 :: Picture -> Picture
rotate90 pic
| (length $ concat pic) == 0 = [ ]
| otherwise = (reverse $ headList pic) : (rotate90 $ tailList pic)
こうやって定義してみると、簡単に作ったように見えるなあ。いいことなんだけど、ちょっと切ない。
Exercises 6.7
rotate90 を使って、反時計回りに90°回転させる関数 rotate270 を定義する。
rotate270 :: Picture -> Picture
Exercises 6.8
Picture と倍率を定義し、Pictureを倍率分だけ拡大する scale 関数を定義する。
scale :: Picture -> Int -> Picture
scale pic num
| num <= 0 = [ ]
| otherwise = concat [ replicate num $ concat $ [ replicate num chr | chr <- line ] | line <- pic ]
replicateとconcatの繰り返し。なんだか汚いなあ。
今後の学習
残Section数 89, 残Exercise数 360