我不明白爲什麼這兩個類似的列表內涵得到不同的結果:類似Haskell的列表理解產生不同的結果
Prelude> let t2s n= [ 1/(2*i) | i <- [1,3..n]]
Prelude> t2s 0
[0.5]
Prelude> let t2s n= [ (2*i) | i <- [1,3..n]]
Prelude> t2s 0
[]
我預計雙方就爭論0
返回[]
。我一定錯過了一些愚蠢的東西?!
我不明白爲什麼這兩個類似的列表內涵得到不同的結果:類似Haskell的列表理解產生不同的結果
Prelude> let t2s n= [ 1/(2*i) | i <- [1,3..n]]
Prelude> t2s 0
[0.5]
Prelude> let t2s n= [ (2*i) | i <- [1,3..n]]
Prelude> t2s 0
[]
我預計雙方就爭論0
返回[]
。我一定錯過了一些愚蠢的東西?!
它與
enumFromThenTo 1.0 3.0 0.0
評估爲[1.0]
事實做。浮球的enumFromThenTo
的規格可在http://www.haskell.org/onlinereport/haskell2010/haskellch6.html的6.3.4節中找到。
首先,我把你的第一個t2s
的名字改爲t1s
,這樣我就可以同時將它們加載到ghci中。看看推斷類型爲他們每個人:
[ts.hs:2:1-33] *Main> :t t1s
t1s :: (Enum t, Fractional t) => t -> [t]
[ts.hs:2:1-33] *Main> :t t2s
t2s :: (Enum t, Num t) => t -> [t]
[ts.hs:2:1-33] *Main>
注意t1s
需要Fractional
參數而t2s
需要Num
。這意味着在t1s 0
中,0
被推斷爲Double
。另一方面,口譯員推斷0
爲t2s 0
中的Integer
。由於參數使用的類型不同,行爲可能會以非常令人驚訝的方式發生變化。特別是,在枚舉列表時,應確保僅使用Integral
類型,如[1,3..n]
。
要解決這個問題,您只需提供兩種函數的顯式類型簽名。
再次違約罷工!基本上,類型推斷找到最一般的類型。問題在於數字文字被重載,所以像't2s 0'這樣的表達式是模棱兩可的 - 它對任何*數字類型都是有效的!由於像這樣的含糊不清是常見的,我們希望能像計算器一樣使用Haskell,所以我們有一個很好的方法來處理它:[默認](http://www.haskell.org/onlinereport/decls.html#sect4 .3.4)。本質上,我們只是先嚐試'Integer',然後嘗試'Double'來獲得像這樣的表達式。你可能想編輯一些關於這個到你的答案。 – 2013-02-22 05:55:12
@TikhonJelvis我是一個Haskell新手,直到您發佈此評論才知道違約。我在這裏發佈的答案只是來自黑客攻擊OP的代碼,因爲我也對這些差異感到好奇。當我通過評估時,我發現了類型差異。 – 2013-02-22 05:57:39
這是一個很好的時間來了解它的任何:)。當我回答一個SO問題時,我實際上首先會讀到它。事實上,我就是這樣撿起一大堆花絮。 – 2013-02-22 06:14:07
對於增加花車,[a,b..c]繼續前進,直到數字超過c +(b-a)/2.0。例如[1.0,2.0..4.0]是[1.0,3.0,5.0]。 – 2013-02-22 04:25:49
你的例子中發生了什麼2.0和4.0? – 2013-02-22 04:44:31
@ Code-Guru。 Mea culpa。我的意思是[1.0,3.0 .. 4.0]。謝謝。 – 2013-02-22 04:52:29