I don't understand why these two similar list comprehensions give different results:
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
[]
I expected both to return []
on argument 0
. I must be missing something silly?!
First of all, I changed the name of your first t2s
to t1s
, so that I can have them both loaded into ghci at the same time. Look at the inferred types for each of them:
[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>
Note that t1s
takes a Fractional
argument whereas t2s
takes a Num
. This means that in t1s 0
, the 0
is inferred to be a Double
. On the other hand, the interpreter infers 0
to be a Integer
in t2s 0
. Since the type used for the argument differs, the behavior can differ in very surprising ways. In particular, you should be sure to use only Integral
types when enumerating a list as in [1,3..n]
.
To fix this, you simply need to provide explicit type signatures for both functions.
It has to do with the fact that
enumFromThenTo 1.0 3.0 0.0
evaluates to [1.0]
. The specification of enumFromThenTo
for Floats can be found in section 6.3.4 of http://www.haskell.org/onlinereport/haskell2010/haskellch6.html .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With