「本物のプログラマはHaskellを使う」をこなしていく。 第一回

勉強しようと思っては何度と無く挫折しているHaskellです。おそらく最大の難関と思われるモナド。例に漏れず僕もモナドがなんだかよくわからない。Functors, Applicatives, And Monads In Pictures - adit.ioが一番わかり易いらしいけど、それでもまだわかった気になれない。数年前に「普通のHaskellプログラミング」は読み通したけど、そこでもモナドは理解できなかった。なるほど、確かに関数の定義や再帰の使い方、mapなどは判った。でも、それではHaskellの本当の便利さを手にしたとは言えないのではないか、と思うのです。僕がメインで使っているScalaも関数型として書いていくのがカッコイイらしく、やはりモナドという言葉は避けて通れません。


なので、初心者向け解説書を一から読んでいこうと思い立った。選んだのはITプロフェッショナルの本物のプログラマはHaskellを使う | 日経 xTECH(クロステック)


第一回だけあってHaskellとはこんな言語です、とかこの連載が目指すこと、といった文章が主。適当に流し読み。Haskellの処理系はDownload Haskell Platformからダウンロードできます。Windows版を選んでインストール。唯一のソースと思える 「ある関数fをn回適用する関数」であるrepeatedを動かしてみた。

 C:\> ghci
 GHCi, version 7.8.3: http://www.haskell.org/ghc/  :? for help
 Loading package ghc-prim ... linking ... done.
 Loading package integer-gmp ... linking ... done.
 Loading package base ... linking ... done.
 Prelude> let repeat f n = \x -> (iterate f x) !! n
 Prelude> :type repeat
 repeat :: (a -> a) -> Int -> a -> a
 Prelude> repeat (+1) 10

 <interactive>:8:1:
     No instance for (Show (a0 -> a0)) arising from a use of ‘print’
     In a stmt of an interactive GHCi command: print it


無名関数のxに値を渡す方法がよくわからないので、エラーになった。エラーの出力もよくわからない。ダメ元でもう一個引数を渡してみたら、ちゃんと動いた。

Prelude> repeat (+1) 10 3
13
Prelude> repeat (*2) 10 2
2048


一つ目では、(+1) という関数を10回繰り返すということを、3という数字に適用している。結果13という答えが帰ってきた。
2つ目では、(*2) という関数を10回繰り返すということを、2という数字に適用している。結果2048という答えが帰ってきた。


この関数は実は結構難しいことをしていると思う。iterate というのは関数fを値xに対して何回も適用するという、いわば無限数列のようなものを返す。それでは答えが得られないので !!n をつかって、最初からn回目の結果を取ってきている。ということが解説されていたので、なるほどなあと思った。


関数内にある無名関数の引数(この場合はx)に値を渡すには、普通の引数として渡す(*1)と良いみたいだ。

Prelude> let plus3 x = \y z -> x + y + z * 2
Prelude> plus3 1 2 3
9

ちゃんと、x=1, y=2, z=3 と渡された。