Julian
Julian

Reputation: 158

Why is [1..n] not handled the same way as [n..1] in Haskell?

I was trying to solve a problem that required the maximum value of a list after being mapped over by a function. The list is a range from a to b where a>b or b>a. Because Haskell can also define decreasing lists i thought that i didn't need to check if a>b and there was no need to flip the bounds to b..a. The function looks somewhat like this:

f a b = maximum . map aFunction $ [a..b]

But if the list is decreasing i.e. a>b then Haskell gives me an exception:

Prelude.maximum: empty list

So for some reason a decreasing list hands over an empty list to the maximum function. Why is that?

I know that maximum is defined in terms of a foldl1 max and that foldl1 needs a non empty list but i don't know why a list like [10..1] is empty when handed to a foldl1.

Upvotes: 6

Views: 4613

Answers (3)

augustss
augustss

Reputation: 23014

They are handled exactly the same way. You start from the first bound and count up.

Upvotes: 3

sclv
sclv

Reputation: 38891

[a..b] desugars to enumFromTo a b. For standard numeric types (modulo a couple of quirks for floating), this keeps adding one until you are >= b. So where b < a this is empty.

You can change the increment by using the following syntax [a,a'..b] which then takes steps in increments of a'-a. So [10,9..1] will be what you want.

Upvotes: 17

undur_gongor
undur_gongor

Reputation: 15954

This is because of the way the sequence is defined in Haskell Report Arithmetic Sequences :

[ e1..e3 ] = enumFromTo e1 e3

and Haskell Report The Enum Class

The sequence enumFromTo e1 e3 is the list [e1,e1 + 1,e1 + 2, ... e3]. The list is empty if e1 > e3.

(emphasis added).

Upvotes: 6

Related Questions