2013-06-10 4 views
13

繰り返しis defined次のように:Preludeでそのままリピートを定義するのはなぜですか?

repeat :: a -> [a] 
repeat x = xs where xs = x:xs 

を、以下が使用されていないことを何らかの理由はありますか?

repeat :: a -> [a] 
repeat x = x : repeat x 

(明らかに多くのプレリュード機能のための多くの等価な定義があるが、私の後者の説明は、単にはるかに明白な感じ。それは仕方のパフォーマンスやスタイルの理由があるのか​​しら。)

+6

[私の答えを見る](http://stackoverflow.com/questions/16632143/why-recursive-let-make-space-effcient/16632403#16632403)。そこでの定義は 'let'を使用しますが、' where'と同じ動作です。 – hammar

答えて

20

それパフォーマンスとスペースの複雑さのためです。

コードの最初のバージョンは明示的な共有を使用しています。基本的にメモリ内の1要素の循環リンクリストのように見えます(コード内のxsは、値がxであり、その末尾がまったく同じリストノードを指すリストノードです)。リストの要素がますます評価されると、同じノードが繰り返し使用されます。

対照的に、repeat xの異なる呼び出しは常に再計算され(メモされないため)、評価されると実際にメモリ内で増加するリストが作成されます。生成されたリストの最後には、まだ評価されていないサンクがもう一つあります。

関連する問題