Reputation: 769
If I enter [5..1]
into the Haskell console it returns []
, whereas I expected [5, 4, 3, 2, 1]
.
In general, [a..b] = []
if a > b
. Why?
Upvotes: 4
Views: 165
Reputation: 153162
The Report covers the details. In Section 3.10:
Arithmetic sequences satisfy these identities:
[ e1..e3 ] = enumFromTo e1 e3
In Section 6.3.4:
For the types
Int
andInteger
, the enumeration functions have the following meaning:
- The sequence
enumFromTo e1 e3
is the list[e1,e1 + 1,e1 + 2,…e3]
. The list is empty ife1 > e3
.For
Float
andDouble
, the semantics of theenumFrom
family is given by the rules forInt
above, except that the list terminates when the elements become greater thane3 + i∕2
for positive incrementi
, or when they become less thane3 + i∕2
for negativei
.
Then the next question is, "Why was the Report specified that way?". There I think the answer is that this choice is quite natural for a mathematician, which most of the original committee were to some extent. It also has a number of nice properties:
[x..y]
has n values, then [x..y-1]
and [x+1..y]
have n-1 values (where in n-1, the subtraction saturates at 0, an ahem natural choice).[x..y]
only requires checking that it is bigger than x
and smaller than y
-- you need not first determine which of x
or y
is bigger.x
, you can write [x..x+n-1]
. If you choose the other rule, where [x..y]
might mean [y,y+1,...,x]
if y
is smaller, there is no way to create an empty list with [_.._]
syntax, so no uniform way to take the next n elements. One would have to write the more cumbersome if n>0 then [x..x+n-1] else []
; and it would be very easy to forget to write this check.If you would like the list [5,4,3,2,1]
, that may be achieved by specifying an explicit second step, as in [5,4..1]
.
Upvotes: 15