morioXのCraftお勉強日記 RSSフィード

2007-06-20

[] Programming with lists (3日目)  Programming with lists (3日目) - morioXのCraftお勉強日記 を含むブックマーク

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 == [ ] = [ ]

 | otherwise = map head list

tailList :: [ [Char] ] -> [ [Char] ]

tailList list

 | list == [ [ ] ] = [ ]

 | otherwise = map tail 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

rotate270 pic = rotate90 $ map reverse pic

高階関数って便利だなあ。教科書的にはもすこし先の章だけど。


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