質問: a : fib b (a+b) -- コンスはリストに要素を追加するものであってリストがなければエラーになるはずです。 -- しかし、上記の例ではエラーになっていません。 ``` ### 質問 なぜこの関数はエラーにならなかったのでしょうか?
回答: Haskellの正確な評価方式についてはまったくの素人なので感覚的なコメントであることをお許しください。 > > しかし自作した関数にはどこにもリストが存在しません。 > > > `fib b (a+b)`の評価結果は[Int]ですから':'の右辺はリストとみなせます。そんなことを考えつつfibの評価の進み具合を考えてみると・・・ => 1 : fib 1 2 => 1 : 1 : fib 2 3 => 1 : 1 : 2 : fib 3 5 => ... 例えば以下まで計算が進んだ状況を考えるとHaskellはfib 3 5が定義に従い[Int]と知っている(整数のリスト以外にはなりえないことを知っている)のでこの式は正当と見做せます。 1 : 1 : 2 : fib 3 5 そこでtake 3とすれば、式末尾のfib 3 5を計算する必要はもはやなく、結果は[1, 1, 2]として計算は完了する・・・そんなふうに考えることができると思います。 また同じことなのですが、ScalaのSeqなど/JavaのStream/C#のLINQのパイプラインの動きに似た動きもイメージしてみました。(実際の計算仕様に近いかどうかはスミマセンがわかりません) 1) take 5は前段(fib)から結果のリストの先頭をまず求めようとする 2) fib 1 1のパターンマッチにより最初の要素は1であることがわかる 3) take 5は最初の要素が求まったのでその要素とtake 4の結果を連結しようとする 4) take 4はさらに前段(fib)からリストの次の先頭を求めようとする ・・・ はなはだ曖昧で不正確かもしれない回答でスミマセン