Why does "enumFromThenTo x x y" depend on "y"?

I'm implementing Enum for a type I have, and I figured it should replicate what ordinary Enum types, so I did some tests on how Enum behaves. I noticed that: "enumFromThenTo 3 3 5" is not the same as "enumFromThenTo 3 3 1". This seems bizarre to me. Generally increasing the stepsize increases the length of the list. For example, "length (enumFromThenTo 0 10 1000) == 101" "length (enumFromThenTo 0 2 1000) == 501" "length (enumFromThenTo 0 1 1000) == 1001" "length (enumFromThenTo 0 0 1000) == infinite" but "length (enumFromThenTo 0 (-10) (-1000)) == 101" "length (enumFromThenTo 0 (-2) (-1000)) == 501" "length (enumFromThenTo 0 (-1) (-1000)) == 1001" "length (enumFromThenTo 0 0 1000) == 0" It would seem to me that "enumFromThenTo x y z == map negate (enumFromThenTo (-x) (-y) (-z))" should be an invariant that should hold but in this case it clearly doesn't. Is this intentional, and if so, for what reason? Or is this a GHC bug?

This behaviour follows directly from the language report [1]:
- The sequence enumFromThenTo e1 e2 e3 is the list [e1,e1 + i,e1 + 2i,…e3
], where the increment, i, is e2 − e1. If the increment is positive or
zero, the list terminates when the next element would be greater than e3;
the list is empty if e1 > e3. If the increment is negative, the list
terminates when the next element would be less than e3; the list is
empty if e1 < e3.
In both "enumFromThenTo 3 3 5" and "enumFromThenTo 3 3 1" the increment is
0. So the list must terminate when the next element would be greater than 5
or 1 respectively.
In this first case 3 > 5 == False, so you get an unbounded list.
In the second case 3 > 1 == True, so you get an empty list.
The above is only specified for the types Int and Integer.
It would be nice to have some laws that govern the behaviour of all Enum
instances (not just Int and Integer). Not just in relation with the Bounded
class.
1 -
https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1310006...
2017-03-24 4:27 GMT+01:00 Clinton Mead
I'm implementing Enum for a type I have, and I figured it should replicate what ordinary Enum types, so I did some tests on how Enum behaves.
I noticed that:
"enumFromThenTo 3 3 5" is not the same as "enumFromThenTo 3 3 1".
This seems bizarre to me. Generally increasing the stepsize increases the length of the list.
For example,
"length (enumFromThenTo 0 10 1000) == 101" "length (enumFromThenTo 0 2 1000) == 501" "length (enumFromThenTo 0 1 1000) == 1001" "length (enumFromThenTo 0 0 1000) == infinite"
but
"length (enumFromThenTo 0 (-10) (-1000)) == 101" "length (enumFromThenTo 0 (-2) (-1000)) == 501" "length (enumFromThenTo 0 (-1) (-1000)) == 1001" "length (enumFromThenTo 0 0 1000) == 0"
It would seem to me that "enumFromThenTo x y z == map negate (enumFromThenTo (-x) (-y) (-z))" should be an invariant that should hold but in this case it clearly doesn't.
Is this intentional, and if so, for what reason? Or is this a GHC bug?
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
participants (2)
-
Clinton Mead
-
Roel van Dijk