2011-02-16 55 views
22

我在我的一個演講中遇到了一個練習,這讓我對[2,2,2]的輸出感到困惑。爲什麼當輸入[2,2 .. 2]時,它會生成一個帶有2的「無限」列表。Haskell範圍表示法生成列表。意外的輸出

我理解符號的方式是第一個元素是開始邊界,第二個是數字之間的「間隙」,最後一個是列表的結束,換言之,當達到該數字時停止。

如果我的推理是正確的,爲什麼表達式[2,2,2]不輸出[2]?


我認爲Haskell可能會這樣評價它;

  1. 當打印的 列表中的第一個元素它等於最後 ,因此停止。或者,如果第一個元素沒有針對「外部」邊界進行檢查,那麼輸出將是[2,2],因爲當向前一個數字加上零(在出現開始邊界2的情況下)時,我們將達到結束,因此停止。

我顯然不正確理解符號的運作,它是如何哈斯克爾計算表達式?

+0

@Robert哈維時,我很好奇,爲什麼你恢復的標籤。這種符號更好地被稱爲範圍符號,而`dot-dot-notation`是一個新的標籤。我可以看到重新添加`dot-dot-notation`標籤的可能推理,但我不明白爲什麼要刪除`range`標籤。 – luqui 2011-02-16 04:48:26

+0

@luqui:`range`可以表示任何東西。我將標籤更改爲`range-notation`並添加了標籤wiki。 – 2011-02-16 05:24:03

回答

33

符號的意思是模仿通常的方式來編寫簡單的序列數學。第二個元素不是步驟,而是實際上列表的第二個元素。其餘的線性推斷從那裏。例子:

[1,2..10] = [1,2,3,4,5,6,7,8,9,10] 
[1,3..10] = [1,3,5,7,9] 
[4,3..0] = [4,3,2,1,0] 
[0,5..] = [0,5,10,15,20,25,30,35... -- infinite 
[1,1..] = [1,1,1,1,1,1,1,1,1,1,1... -- infinite 

原因[2,2..2]是無限的,因爲沒有列表的值,則總是比右邊的終點,這是終止條件高。如果您希望步驟爲2,則應該編寫[2,4..2],它給出預期的輸出[2]。 (所以我想這不是列表中的實際第二個元素,但你看到的邏輯)

+1

那個優秀的夥伴,很好的解釋,特別是; *「是無限的,因爲沒有任何列表的值是**比正確的端點更大**」*這是我主要困惑的。所有最好的 – Carlos 2011-02-16 03:45:29

26

基本上是因爲標準規定的。 [e1, e2 .. e3] desugars到enumFromThenTo e1 e2 e3

section 6.3.4 the Haskell '98報告說:

序列enumFromThenTo E1 E2 E3是列表[E1,E1 + 1,E1 + 2 1,... E3],其中增量,我,是e2-e1。如果增量爲正數或零,則列表在下一個元素大於e3時終止;如果e1> e3,則列表爲空。如果增量爲負值,則列表在下一個元素小於e3時終止;如果e1 < e3,該列表是空的。

下一個元素是從來沒有超過2