类似的Haskell列表理解具有不同的结果

时间:2013-02-22 03:30:17

标签: haskell list-comprehension

我不明白为什么这两个相似的列表推导会给出不同的结果:

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。我一定错过了傻事?!

2 个答案:

答案 0 :(得分:7)

首先,我将您的第一个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中推断Integert2s 0。由于用于参数的类型不同,行为可能以非常令人惊讶的方式不同。特别是,在枚举Integral中的列表时,您应确保仅使用[1,3..n]类型。

要解决此问题,您只需为两个函数提供显式类型签名。

答案 1 :(得分:6)

这与

的事实有关
enumFromThenTo 1.0 3.0 0.0

评估为[1.0]。 Floats的enumFromThenTo规范可以在http://www.haskell.org/onlinereport/haskell2010/haskellch6.html的第6.3.4节中找到。