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