[Haskell-cafe] Why does [1.0, 3 ..4] contain 5?

Bence Kodaj bence.kodaj at gmail.com
Wed Oct 19 12:13:04 UTC 2016


Hi all,

Does anybody happen to know why [1.0, 3 ..4 ] is [1.0, 3.0, 5.0] ?

I do realize I'm not supposed to use enumerated lists with doubles, so this
is just a question out of pure curiosity. I ran into this example
accidentally, and I find it counter-intuitive - I would naively expect that
[x, y .. z] does not contain elements greater than z (assuming x < y < z).

The root cause of why [1.0, 3 .. 4] contains 5.0 is that in the Enum
instances for Double and Float, enumFromThenTo is defined like this:

numericEnumFromThenTo
<http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#numericEnumFromThenTo>
e1 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413496>
e2 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413497>
e3 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413498>
   = takeWhile <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.List.html#takeWhile>
predicate <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413500>
(numericEnumFromThen
<http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#numericEnumFromThen>
e1 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413496>
e2 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413497>)
                               where
mid <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413499>
= (e2 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413497>
- e1 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413496>)
/ <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#%2F>
2                                 predicate
<http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413500>
| e2 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413497>
>= e1 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413496>
 = (<= e3 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413498>
+ <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Num.html#%2B>
mid <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413499>)
                                          | otherwise
<http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Base.html#otherwise>
= (>= e3 <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413498>
+ <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Num.html#%2B>
mid <http://hackage.haskell.org/package/base-4.9.0.0/docs/src/GHC.Real.html#local-1627413499>)

and with the concrete values in the example, the predicate becomes (<=5.0).


My question is this: why can't we simply use (<= e3) as the predicate? Why
is the upper limit  (e3) increased by half of the length of the e1 .. e2
interval (mid)? Can someone give an example where using (<=e3) as predicate
would give a bad result?

I'm guessing that the answer has something to do with the quirks of
floating-point arithmetic (rounding etc.), of which I'm not an expert at
all :)

Regards,
Bence
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20161019/22fc9fbe/attachment.html>


More information about the Haskell-Cafe mailing list