2011-07-24 104 views
19

我對Haskell很新。有人可以解釋爲什麼定義這樣的列表返回一個空列表Haskell遞減範圍

ghci> let myList = [10..1] 
ghci> myList 
[] 

但是,這個工作正常。

ghci> let myList = [10, 9..1] 
ghci> myList 
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1] 

回答

34

基本上,因爲[10..1]被轉換爲enumFromTo 10 1本身具有的語義通過取所有元素低於1從(包括)10向上計數(具有步長+1),其導致創建列表。

鑑於[10, 9..1]被轉換爲enumFromToThen 10 9 1其中明確規定的計數步長作爲9-10,即-1(它是硬編碼到+1enumFromTo

更精確的規範可以在Haskell的報告中找到( 6.3.4枚舉類):

enumFrom  :: a -> [a]   -- [n..] 
enumFromThen :: a -> a -> [a]  -- [n,n'..] 
enumFromTo  :: a -> a -> [a]  -- [n..m] 
enumFromThenTo :: a -> a -> a -> [a] -- [n,n'..m] 

對於類型IntInteger,枚舉函數甲肝E以下含義:

  • 序列enumFrom e1是列表[e1,e1+1,e1+2,...]

  • 序列enumFromThen e1 e2是列表[e1,e1+i,e1+2i,...],其中增量i是e2-e1。增量可以是零或負數。如果增量爲零,則所有列表元素都是相同的。

  • 該序列enumFromTo e1 e3是列表[e1,e1+1,e1+2,...e3]。如果e1 > e3該列表爲空。

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

+0

謝謝你,這是有道理的。乍一看,我認爲這是非常愚蠢的表示,但我現在可以看到,它可以定義範圍內的步驟的大小。很酷!非常興奮Haskell現在:) – Christopher

11

算術序列符號僅僅是用於從Enum類函數語法糖。

[a..]  = enumFrom a 
[a..b] = enumFromTo a b 
[a, b..] = enumFromThen a b 
[a, b..c] = enumFromThenTo a b c 

至於爲什麼他們沒有被定義爲自動反轉,我只能猜測,但這裏有幾個可能的原因:

  • 如果ab在別處定義,這將是更難一目瞭然地告訴[a..b]會走向哪個方向。

  • 它有更好的數學性質來推理。您不必爲順序顛倒時添加特殊情況。

2

如果你想生成ab列表無論a < b,您可以使用以下命令:

[a, a + (signum $ b - a)..b]

+1

請注意,這將產生一個無限列表,如果'a = b'。 – hammar

+0

@hammar我站在更正:) – dionyziz