7

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

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。我一定是错过了什么愚蠢的东西?!

4

2 回答 2

7

首先,我将您的第一个名称更改t2st1s,以便我可以将它们同时加载到 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 00被推断为Double。另一方面,解释器推断0为 a Integerin t2s 0。由于用于参数的类型不同,因此行为可能会以非常令人惊讶的方式不同。特别是,您应该确保Integral在枚举列表时仅使用类型,如[1,3..n].

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

于 2013-02-22T03:56:39.420 回答
6

这与以下事实有关

enumFromThenTo 1.0 3.0 0.0

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

于 2013-02-22T04:15:26.400 回答