質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

Q&A

解決済

1回答

1428閲覧

遅延評価に対する疑問

moeii

総合スコア12

Haskell

Haskellは高い機能性をもった関数型プログラミング言語で、他の手続き型プログラミング言語では難しいとされている関数でも容易に行うことができます。強い静的型付け、遅延評価などに対応しています。

0グッド

0クリップ

投稿2017/04/02 08:34

###前提・実現したいこと
フィボナッチ数列求める関数を作成しました。

Haskell

1fib :: Int -> Int -> [Int] 2fib a b = a : fib b (a+b)

以下が出力です

Haskell

1Prelude > take 5 $ fib 1 1 2[1,1,2,3,5] 3コード

###疑問
そこで実行してて疑問に思ったことがあります。
説明が苦手なのでコードと一緒に書きます。

Haskll

1-- コンスを使ってリストの先頭に追加している。 2Prelude > 1:[] 3[1] 4Prelude > []:[] 5[[]] 6Prelude > 1:[2,3] 7[1,2,3] 8Prelude > 1:1:2:4:5:[] 9[1,1,2,3,4,5] 10 11-- これはエラーになる 12Prelude > 1:1 13 14-- しかし自作した関数にはどこにもリストが存在しません。 15Prelude > fib a b = a : fib b (a+b) 16 17-- コンスはリストに要素を追加するものであってリストがなければエラーになるはずです。 18-- しかし、上記の例ではエラーになっていません。

###質問
なぜこの関数はエラーにならなかったのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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)からリストの次の先頭を求めようとする

・・・

はなはだ曖昧で不正確かもしれない回答でスミマセン

投稿2017/04/02 09:46

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問