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
.
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.
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).
() 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 () .
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.
[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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With