2016-09-17 15 views
3
integerList = [1] ++ integerList 

(head (tail integerList)) 

私はこのコードを実行しました。結果は1であり、無限の再帰であることがわかりました。 私はhaskellがこれらの関数をどのように計算するかを理解しようとしています。誰かがプロセスを書き留めることができます。私はそれを視覚化したいと思います。ありがとう!ハスケル関数のプロセス

+3

キーワードは[lazy evaluation](https://wiki.haskell.org/Lazy_evaluation)です。 – bereal

+0

これは私の理解から、これは私が起こっていると思います。 head(tail [1,1] ++ integerList)? – DoubleOseven

+0

これは代わりに次のようになります:head(tail [1] ++([1] ++ integerList))? – DoubleOseven

答えて

4

headは、リストの最初の要素を返します。この場合、リストtail integerListの最初の要素を返します。 tailは最初の要素のない元のリストを返します。元のリストはintegerListで、これは[1] ++ integerListにバインドされています。 ++演算子は2つのリストを連結するため、結果のリストは1 : integerListです。 tailをこのリストに適用するとintegerListとなるので、tail integerListは単にintegerListとなります。

先頭へ戻るtail integerListintegerListと置き換えてください(これは評価されているため)head integerListを取得してください。お知らせ:integerList1 : integerListと評価されます。 headを適用すると、1が得られます。

+0

注目すべき重要なポイントは、 '++ 'は' 1:integerList'を返すために 'integerList' *を評価する必要はないということです。 – chepner

+1

d3daveありがとうございます。それは今完璧な意味があります! :)ありがとうございます – DoubleOseven

2

のは、定義を拡張してみましょう:

    __________ 
       /  \ 
       |   | 
       V   | 
       +---+---+---+ | 
integerList = | : | o | o | | 
       +---+-|-+-|-+ | 
        | \___/ 
        V 
        +---+ 
        | 1 | 
        +---+ 

あなたが書かれていたかのように:

integerList = [1] ++ integerList 
integerList = foldr (:) integerList [1] -- inline (++) 
integerList = 1 : integerList   -- inline foldr 

今ではintegerListはものの無限のストリームを表す、循環的にリンクされたリストであることは明らかです次のC:

tailintegerListintegerListであり、head1である。 takedropWhilefoldrのような多くの標準的なプレリュード関数を使用して、無限のストリームを操作することができます。たとえば、take 5 integerList[1, 1, 1, 1, 1]を生成します。 repeat関数:integerList = repeat 1を使用してintegerListを定義することもできます。

+0

すばらしい視覚ガイドをありがとう! :) – DoubleOseven