Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell range notation to generate list. Unexpected output

I came across an exercise in one of my lectures that left me confused on the output of [2, 2 .. 2]. Why when entering [2, 2 .. 2] it generates an "infinite" list with 2's.

The way i understood the notation was that the first element is the start bound, the second the "gap" between the numbers, and the last is the end of the list, in other words stop when reaching that number.

If my reasoning is right, why does the expression [2, 2 .. 2] not output [2]?.


I thought Haskell might evaluate it this way;

  1. When printing the first element of the list it is equal to the last, therefore stop.
  2. Or, if the first element is not checked against the "outer" bound, then the output would be [2, 2] because when adding zero to the previous number (in out case the start-bound 2) we would have reached the end and therefore stop.

I obviously do not understand the workings of the notation correctly, so how does Haskell evaluates the expression?

like image 873
Carlos Avatar asked Feb 16 '11 03:02

Carlos


2 Answers

The notation is meant to mimic the usual way to write simple sequences mathematics. The second element is not the step, but in fact the actual second element of the list. The rest is linearly extrapolated from there. Examples:

[1,2..10] = [1,2,3,4,5,6,7,8,9,10]
[1,3..10] = [1,3,5,7,9]
[4,3..0]  = [4,3,2,1,0]
[0,5..]   = [0,5,10,15,20,25,30,35...  -- infinite
[1,1..]   = [1,1,1,1,1,1,1,1,1,1,1...  -- infinite

The reason [2,2..2] is infinite is because no value of the list is ever greater than the right endpoint, which is the terminating condition. If you want the step to be 2, you should write [2,4..2], which gives the expected output [2]. (So I guess it's not the actual second element of the list in all cases, but you see the logic)

like image 60
luqui Avatar answered Nov 04 '22 20:11

luqui


Basically because the standard specifies so . [e1, e2 .. e3] desugars to enumFromThenTo e1 e2 e3

In section 6.3.4 the Haskell '98 report says:

The sequence enumFromThenTo e1 e2 e3 is the list [e1,e1+i,e1+2i,...e3], where the increment, i, is e2-e1. If the increment is positive or zero, the list terminates when the next element would be greater than e3; the list is empty if e1 > e3. If the increment is negative, the list terminates when the next element would be less than e3; the list is empty if e1 < e3.

The next element is never greater than 2.

like image 27
wnoise Avatar answered Nov 04 '22 21:11

wnoise