2017-11-02 3 views
-1

この1:私はワンライナーHaskellのフィボナッチを理解していない

fib = 1 : 1 : [a + b | (a, b) <- zip fib (tail fib)] 

私が最初fibであることを理解し、[1、1、..]

..リストの=残り)ので、ここでfib = [1, 1, ..]

tail fib = [1, ..]はとても(a, b)あるa + bに変換(1, 1)です210今リストは以下のようになります。

fib = 1 : 1 : 2 : [a + b | (a, b) <- zip fib (tail fib)] 

とここで私は混乱:

今私はfib[1, 1, 2, ..]tail fibだと思うが[1, 2, ..] であると私はリストをzipた場合、私は再びそれを取得する必要がありますa + bそれらはまだ2つのリストの最初の要素なので、1 + 1です。 どこが間違っていますか?

(私は私は知っているが、私は理由を理解することはできませんし、何がここで起こっている)

+0

私は既にそこに尋ねたが、誰もこの投稿をもう見ないと思う:-) – Elimelech

+0

そこにはすばらしい答えがたくさんある。非アクティブな質問は、もう一度それを聞く良い理由ではありません。私はこの質問を閉じるために投票しています。 – AJFarmar

+0

私はそこに知っているが、私はここで理解できない何かがある。私はあなたがそこに尋ねるのを見たが、答えは得られなかった。 – Elimelech

答えて

2

あなたは

fib = 1 : 1 : [a + b | (a, b) <- zip fib (tail fib)] 

は、次の要素が2であることを生成することを正しいしかし、fib = 1 : 1 : 2 : [a + b | (a, b) <- zip fib (tail fib)]があります次のステップでは正確ではありません。このステップでzip fib (tail fib)を評価するので、それはそのままではなくその定義から置き換えなければなりません。より正確な式のようなものになります。

fib = 1 : 1 : 2 : [a + b | (a, b) <- zip (tail fib) (tail (tail fib)] 

zipの評価を考えるための一つの方法は、各アプリケーションが与えられたリストのそれぞれの次の2つのヘッド要素を消費することです。この場合、次の反復は(a, b) = (1, 2)を返します。これは、それぞれfib(tail fib)の次の数字のペアであるためです。

+0

何が混乱しているのは、常に変化しているフィブです。私がすでに知っている2つのリストではなく、一緒にまとめています。リストの理解では、私はすべての反復を「呼び出す」ことができ、それはすべての「呼び出し」で異なっています。 – Elimelech

+1

@mosheあなたの評価は間違っています。あなたは '' fib' ** once **を '' zip'のパラメータとして呼び出します。次に、 'zip'が評価され、' fib'を消費します。 –

+1

@mosheまた、Haskellは遅延評価を使用しています。リスト 'fib 'の要素は、' zip'がそれらを要求するときに評価されます。これがこのソリューションが機能する主な理由です。 –

関連する問題