2013-11-03 54 views
4

我看到了這段代碼來生成斐波那契數。Haskell如何生成這個無限列表?

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

可以類似風格的代碼被寫入產生無限的名單[1 ..]

我在Haskell網站上看到這個link on cyclic structures

有給出一個例子

cyclic = let x = 0 : y 
     y = 1 : x 
    in x 

我想在一個循環的方式來定義我的問題的列表,但未能成功。 我想要的是一個根據其本身定義的列表,並且在Hasekll中評估爲[1 ..]。

注:Haskell [1..]評估爲[1,2,3,4,5...]而不是[1,1,1...]

+0

'ones = 1:ones' –

+0

這個和Haskell中的'[1 ..]'不一樣。當你的計算結果爲[1,1,1,1 ...]'時,Haskell'[1 ..]'評估爲[1,2,3,4,5 ...]'。 –

+0

啊,好的。 'nats = 1:map(+1)nats'。 –

回答

8

下應該給你想要的結果:

nats = 1 : map (+1) nats 

或者,更地道:

nats = iterate (+1) 1 

這很容易明白爲什麼第一個片段通過使用等式推理計算爲[1,2,3...]

nats = 1 : map (+1) nats 
    = 1 : map (+1) (1 : map (+1) nats) 
    = 1 : map (+1) (1 : map (+1) (1 : map (+1) nats)) 
    = 1 : 1 + 1 : 1 + 1 + 1 : .... 
    = [1,2,3...] 
+0

'nats = iterate succ 1'在我看來給出了一個更好的直覺。反覆應用後繼函數自然會產生一組自然。 – kqr

+0

@kqr:如果你從零開始,那就是! – yatima2975

5

是的。

想想你怎麼能寫出你的列表中的每個元素:

1 
1 + 1 
1 + 1 + 1 
1 + 1 + 1 + 1 
1 + 1 + 1 + 1 + 1 

每個條目後,以後每一項都有一個額外的+ 1。所以我們想從1開始,然後將1添加到每個後續元素。然後,我們想要採取第二個元素,然後添加1

下面是我們如何能做到這一點:

let xs = 1 : map (+ 1) xs 

這擴大這樣的:

1 : map (+ 1) xs 
1 : (1 + 1) : map (+ 1) xs 
1 : (1 + 1) : ((1 + 1) + 1) : map (+ 1) xs 

等。