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

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

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

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.
Reply | Threaded
Open this post in threaded view
|

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

Roel van Dijk-3
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.


2017-03-24 4:27 GMT+01:00 Clinton Mead <[hidden email]>:
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.


_______________________________________________
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.