我不明白为什么这两个类似的列表内涵得到不同的结果:类似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