![]() |
![]() |
![]() |
![]() |
Haskell は簡単なことと難しいことが入れ替わったような言語で、 IO などの普通の言語ではなんでもないことが難しく、探索、構文解析などの むずかしいことが比較的簡単に出来ます。
Haskell は純粋な関数型なので、代入に伴うバグを気にしないですみます (参照透明性があるといいます)。また、 値は必要になって初めて求められるので、無限の大きさをもつデータを扱うことが出来ます。
例えば、奇数の最初の3つが欲しいときは
take 3 [1,3..]と書くことが出来ます。 遅延評価を行わない普通のプログラミング言語では、途中に無限ループがあると そこで止まってしまいますが、Haskell の場合は必要な値だけを計算して、 最後まで実行してくれます。
Haskell のプログラムは、値を求める手順ではなく、値の定義を書いたものなので、 数学の本に載っている数式の定義がほぼそのまま使えます。特に、再帰的な定義はすっきり書けます。
階乗
fact 0 = 1 fact n = n * fact (n-1)quick sort
qsort _ [] = [] (1) qsort f (x:xs) = before ++ (x : after) (2) where before = qsort f (filter (not . (f x)) xs) (3) after = qsort f (filter (f x) xs) (4)注:
Main> qsort (>) [3,1,5,2,10,0] [10,5,3,2,1,0]数列
-- 等比数列などの次の項が今の項の関数であらわされる無限数列(初項 a0、 関数 f) seqn a0 f = a0 : seqn (f a0) f -- (1) -- 初項 a0 公比 r の等比数列 geo a0 r = seqn a0 (*r) -- Fibonacci 数列 fib = 1:1:zipWith (+) fib (tail fib)(1) はほとんどトートロジー(単なる言い換え)ですが、ちゃんと計算してくれます。 この様な数列の定義は一見無駄な計算をしているように見えますが、そのようなことはなく、 O(n) のオーダーです。
a0 = a0 an+1 = f(an)で表される無限数列であることの証明は ここ を見てください。
上の例でも分かるように、コードには”どういう値が欲しいか?”を記述するだけです。 その値をどういう手順で求めるかについてはほとんど気にする必要がありません。
このことから、下で示すような種類のプログラムでは有効です。
このことから、Haskell は Fortran ユーザー、AI プログラマにとっては 便利だと思います。もちろん、実行速度は Fortran に比べてかなり遅いのですが、 GHC には profiler が付いているので、bottle-neck を見つけることが出来ます。 そして、もし、どうしても必要ならその部分を C で書き直せば速度は改善されます。
大雑把な感じとしては、GHC でコンパイルした Haskell プログラムは Python のプログラムと同じくらいの 速度です。つまり、多くの場合ほとんど問題が無いが、速度が気になるプログラムでは問題になります。
以下に主な Web site を挙げておきます。
![]() |
![]() |
![]() |
![]() |