Cogito Ergo Sum.

我思う故に我あり

6日目のFizzBuzz

・6日目のFizzBuzz

main = loop 1 100
loop n limit
    | n > limit = return ()
    | otherwise = do
        putStrLn(fizzBuzz n)
        loop (n + 1) limit
fizzBuzz x
    | x `mod` 15 == 0 = "FizzBuzz"
    | x `mod`  5 == 0 = "Buzz"
    | x `mod`  3 == 0 = "Fizz"
    | otherwise       = show x

 根っからの「手続き型志向」「命令型思考」プログラマである当方、「1日目のFizzBuzz」を更に「退化」させたコードが可能であることがわかり、正直ホッとした(笑)。結局「逐次」処理しか僕にはわかんないんだよな。僕の頭の中にあるのは「チューリングマシン」だけなので…。

 『プログラミングHaskell』(Hutton(著) 山本(訳) オーム社 2009年)は品があってとても良い本だと思うけど、元々がイギリスの情報系の大学の教科書として書かれたもので、毎週の講義をただ「聞く」だけでなく、指導員のいる大学のコンピュータ実習室での実習や自主学習を通して各章の例題や章末の練習問題等に取り組み、Haskellや「関数型プログラミング」そのものに対する理解を深めていくことが前提となっている。「読むだけでスラスラわかる!」というタイプの本ではない(ただし、例示されるコード例や練習問題の内容は本当によく考えられていると思う)。

 抽象的な概念の説明に関しては、(正直に言えば)読むだけではよくわからないことが多い。例えば、「カリー化」や「関数の部分適用」の説明のために費やされているのはたったの1ページで、僕は「カリー化」という概念を既に知っていたので読み進めることができたが、初めてならサッパリわからなかっただろうと思う。概念は「コードを実行してみればわかる」というものではないしなぁ…。その辺りが関数型言語を学ぶ難しさか(もっとも、命令型(手続き型)言語でも、「コードを実行してみればわかる」のは今や昔ながらのC言語くらいか…?)。

 まぁ、今ではHaskellに関する(日本人著者によって書かれた)日本語の本もたくさんあるし…、いろいろ読み漁っていればそのうちわかるようになるだろう(と甘い期待を抱いているのだが…(笑))。

 Haskellは同じことを実現するにしてもいろいろな書き方が可能で、それはHaskellの魅力の1つなんだろうけど、頭の悪い僕には少々厄介(涙)。例えば関数を1つ定義するにしても、条件式、ガード付きの等式、パターンマッチ(値、リスト、タプル…)、リスト内包表記、再帰的定義、λ(ラムダ)式による定義…、といろいろできて、かえってそれが難しい。

 でも考えてみれば、「いろいろな書き方が可能で、頭の悪い僕には少々厄介」というところはRubyも全く同じ。そのRubyが僕は大好きなので、Haskellも大好きになる可能性はある。

 でも、あれだな。Rubyに感じる「評価(eval)して意味をなすなら何でもアリ」の無茶苦茶感はLispSchemeには感じるけど、Haskellにはまだ感じないな。あの「何でもアリ」の無茶苦茶なところを「数学的に整理した」ってのがHaskellなのかな。

 LispSchemeについてはちょっと齧っただけだけど、「リスト」そのものについて考える時間が一番長いように思う。ところが、Haskellは「型」について考える時間が一番長い(『プログラミングHaskell』は読者がそう感じるようになるように書かれているように思う)。OCamlやF#とかだとどうなんだろう?

 学習し始めの躓きポイントとしては…、些細な話だけど、Haskellは記号の使い方が独特で…(関数型言語としては普通なのかもしれないけど)、「"」「'」「`」「^」「^^」「&&」「||」「|」「\」「<-」「->」「=>」「>>=」「/=」「$」「.」「,」「::」「+」「++」「+++」「--」「{--}」等々、「記号の入力」で既に戸惑っている(笑)。

 ま、この「戸惑い」も最初のうちだけだろう。この「戸惑い」を今は楽しもう!