我不明白为什么这两个相似的列表推导会给出不同的结果:
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
。我一定错过了傻事?!
答案 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
中推断Integer
为t2s 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节中找到。