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?
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?
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
IntandInteger, the enumeration functions have the following meaning:
- The sequence
enumFromTo e1 e3is the list[e1,e1 + 1,e1 + 2,…e3]. The list is empty ife1 > e3.For
FloatandDouble, the semantics of theenumFromfamily is given by the rules forIntabove, except that the list terminates when the elements become greater thane3 + i∕2for positive incrementi, or when they become less thane3 + i∕2for 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].