7

Haskell için oldukça yeni ve Fibonacci dizilerinin tembel ifadesinin nasıl çalıştığını kafamın etrafına sarmaya çalışıyorum.Haskell Fibonacci Açıklama

Bunun daha önce sorulmuş olduğunu biliyorum, ancak cevapların hiçbiri sonucu görselleştirmekle uğraştığım bir sorunu gidermedim.

  1. zipWith anlamıyla bir liste
  2. ilk elemanı ancak birlikte iki listeyi
  3. tail kapmak tüm fermuarlar:

    kod zipWith

    fibs = 0 : 1 : zipWith (+) fibs (tail fibs) 
    

    Aşağıdakileri anladım kullanarak standart biridir

  4. Haskell, 'to-be' hesaplanmış veriyi thunks olarak göndermektedir. Benim anlayış

, ilk [0,1,<thunk>] ve [1,<thunk>][1,<thunk>] vermek zipWith (+) kullanarak ekler.

Neden: Yani şimdi

fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs) 

Ben google'dan ettik referanslar Bir çok sonra Sorum şudur

fibs = 0 : 1 : 1 : zipWith (+) [1,1,<thunk>] ([1,<thunk>]). 

yukarıdaki çizgiyi "görselleştirmek" yolunu seçerler var sadece
[1,1,<thunk>] yerinekarşılık gelen yukarıda doğrultusunda fibs bileşeni?

fibs tüm listeyi içermemeli ve <thunk>? zipWith zaten öğelerin ilk çifti işledi çünkü

+0

iyi bir yol biz kademeli erişmeyi olarak örneğin 3 almak 'in (varlık haline geldiğini (http://stackoverflow.com/a/20978114/849891) [geçici değerlere isim] etmektir fibs'). Böylelikle, aynı veriden iki kere (aynı adla) veya iki eşit veri parçası (her biri kendi adına sahip) arasında bir karışıklık yoktur. –

cevap

11

Bu ara adım yanlıştır:

fibs = 0 : 1 : 1 : zipWith (+) fibs (tail fibs) 

zipWith genel durumda ne Hatırlama:

zipWith f (x:xs) (y:ys) = (f x y) : zipWith f xs ys 

size tanımını doğrudan uygularsak Bu genişleme elde edin:

fibs = 0 : 1 : zipWith (+) fibs (tail fibs)    # fibs=[0,1,...] 
    = 0 : 1 : zipWith (+) [0,1,...] (tail [0,1,...])  # tail fibs=[1,...] 
    = 0 : 1 : zipWith (+) [0,1,...] [1,...]    # apply zipWith 
    = 0 : 1 : (0+1 : zipWith (+) [1,0+1,...] [0+1,...]) 
    = 0 : 1 : 1 : zipWith (+) [1,1,...] [1,...]   # apply zipWith 
    = 0 : 1 : 1 : (1+1 : zipWith (+) [1,1+1,...] [1+1,...]) 
    = 0 : 1 : 1 : 2 : zipWith (+) [1,2,...] [2,...]  # apply zipWith 
    = 0 : 1 : 1 : 2 : (1+2 : zipWith (+) [2,1+2,...] [1+2,...]) 
    = 0 : 1 : 1 : 2 : 3 : zipWith (+) [2,3...] [3,...] # apply zipWith 
    : 
+0

+1 Açıklama için teşekkürler, @Joni. Şimdi anlamaya başladığımı düşünüyorum, ama hala orijinal soruma hangi türden bağlantılar olduğunu soruyorum. Fibreleriniz olduğu dördüncü satırınızda = 0: 1: 1: zipWith (+) [1,1, ...] [1, ...], zipWith (+) 'den sonraki liste, tüm liste yerine yalnızca [1,1, ...]' e sahip olur? – MikamiHero

+1

zipWith, bir çift öğeyi alır, onlara bir işlev uygular ve giriş listelerinin * kuyruklarına * girer. Belki de bunu genişletmeyi düşünmüyorsam, – Joni

+0

'u genişletmeliydim, bunu takdir ediyorum. ! Haskell için çok yeni ve bu benim başımı bir döngü içinde tuttu – MikamiHero

1

Nasıl görselleştirilir? Devam ediyor.

1 1 2 3 5 8 13 <----fibs 
    1 2 3 5 8 13  <----The tail of fibs 
+________________ <----zipWith (+) function 
    2 3 5 8 13 21  <----New fibs. 13 drops out --nothing to zip with 

finally, add [1, 1] to beginning 
1, 1, 2, 3, 5, 8, 13, 21 

böyle tanımlarını anlamak için