Haskell range notation to generate list. Unexpected output

10,568

Solution 1

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)

Solution 2

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.

Share:
10,568

Related videos on Youtube

Carlos
Author by

Carlos

Updated on July 16, 2020

Comments

  • Carlos
    Carlos almost 4 years

    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?

  • Carlos
    Carlos about 13 years
    That excellent buddy, great explanation, especially; "is infinite because no value of the list is ever greater than the right endpoint" which is what I was mainly confused about. All the best
  • Nick Sweeting
    Nick Sweeting about 9 years
    This was the key to me understanding it: "If you want the step to be 2, you should write [2,4..2]". Start with two, linearly go up but stop before the next element is greater than 2, which happens to be after only 1 element.

Related