1st 5sptes

Haskell を学ぶため色々調べてはいるが、いまいち内容が理解できていない。Google 先生は色々教えてくださるっているのに、いかんなくダメ生徒っぷりを発揮。こりゃ、学ぶ方法に問題ありだな。いきなり何か書いてみようとして、わからない事があったら検索して... ってやっているもんだから。今までの言語はそれで何とかなっていたんだが、Haskell はちょっと難しい(センスがないってのもあるんだろうけど)。まずは基礎を固めよう、と思う。固まるかな。

お手本

Haskell in 5 steps - HaskellWiki
環境のセットアップと、Hello world!はすでにやったのでステップ 4 から。

4 Haskell the calculator

階乗の計算だね。

Prelude> let fac n = if n == 0 then 1 else n * fac (n-1)
Prelude> fac 42
1405006117752879898543142606244511569936384000000000

if じゃなく、パターンマッチを使うとこうなる。Wikiではコンパイルして実行しているけど、インタプリタでいいや。

Prelude> let fac 0 = 1; fac n = n * fac (n - 1)
Prelude> fac 42
1405006117752879898543142606244511569936384000000000

これは問題なし。

4.1 Write your first parallel Haskell program

並列処理のコードだ。`par` を加える事で並列処理になるようだ。
お手本通り Control.Parallel を import してコンパイルすると、次のエラーが出た。

% ghc -O2 --make A.hs -threaded

A.hs:1:7:
    Could not find module `Control.Parallel':
      Use -v to see a list of the files searched for.

GHC.Conc を import してコンパイルが通るようになった。

-- import Control.Parallel
import GHC.Conc

main = a `par` b `par` c `pseq` print (a + b + c)
  where
    a = ack 3 10
    b = fac 42
    c = fib 34

fac 0 = 1
fac n = n * fac (n - 1)

ack 0 n = n + 1
ack m 0 = ack (m - 1) 1
ack m n = ack (m - 1) (ack m (n - 1))

fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)

fac は階乗、fib はフィボナッチ、ack は何?まあいい、それは置いておこう。問題は par と pseq だ。

式(x `par` y)は、xの(弱頭部正規形までの)評価を発火させ、yを返す。
(略)
seqはどちらの引数を先に評価することもあるが、pseqは最初の引数を二番目の引数より先に評価することが決まっているので、parと組み合わせて評価順を制御するにはこちらの方が適している。

http://www.kotha.net/ghcguide_ja/6.12.1/lang-parallel.html#id3031662

par がスレッドの分岐点になるみたい。x は返されないんだね。pseq は seq と同じ事をするようだ。seq が何をするのかは知らないけど...。正格評価ね。あとで調べておくよ。
で、ソースはというと、par と pseq の説明があればおおよその動作は理解できる。

5 Where to go from here

なんだ、5steps って言うからもう一つサンプルがあるかと思ったよ。次はどうしよう、Haskell in 10 minutes かな。