Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

list

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.

like image 588
Julian Avatar asked Sep 08 '11 13:09

Julian


People also ask

How does cons work in Haskell?

Internally, Haskell lists are represented as linked cons-cells. A cons-cell is like a C struct with two pointer fields head and tail. The head field points to the first element of the list, the tail field to the rest of the list.

What does /= in Haskell mean?

The /= operator means "is not equal". It's supposed to be reminiscent of the mathematical "≠" symbol (i.e., an equals sign with a diagonal line through it).

What does () mean in Haskell?

() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .

What does just mean in Haskell?

It represents "computations that could fail to return a value". Just like with the fmap example, this lets you do a whole bunch of computations without having to explicitly check for errors after each step.


2 Answers

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

like image 147
sclv Avatar answered Oct 05 '22 23:10

sclv


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

like image 41
undur_gongor Avatar answered Oct 06 '22 00:10

undur_gongor