「本物のプログラマは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 と渡された。