Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the range operator on lists leads to infinite expansion

Tags:

haskell

I'm learning Haskell at the moment from "Learn You a Haskell".

I am looking at lists and building them using ranges.

Would I be right in thinking that if I have a list like

[2,4..20]

what haskell does is to get the difference between the first two elements and then add that to 4 to get the subsequent value?

which brings me to my next point. I tried [1,1..20] and it resulted in a never ending list expansion because 1-1 = 0 and so there is no arithmetic progression.

Is my thinking correct?


1 Answers

The Haskell Report is the definitive reference. It has this to say about arithmetic sequences:

Translation: Arithmetic sequences satisfy these identities:

[ e1.. ]      = enumFrom e1
[ e1,e2.. ]   = enumFromThen e1 e2
[ e1..e3 ]    = enumFromTo e1 e3
[ e1,e2..e3 ] = enumFromThenTo e1 e2 e3

where enumFrom, enumFromThen, enumFromTo, and enumFromThenTo are class methods in the class Enum as defined in the Prelude (see Figure 6.1).

The semantics of arithmetic sequences therefore depends entirely on the instance declaration for the type t. See Section 6.3.4 for more details of which Prelude types are in Enum and their semantics.

So, we should go looking at the enumFromThenTo method of the appropriate type. Let's assume we're talking about Integer here. The chapter on predefined types and classes has this to say about Enum instances:

For the types Int and Integer, the enumeration functions have the following meaning:

  • The sequence enumFrom e1 is the list [e1,e1 + 1,e1 + 2,…].
  • The sequence enumFromThen e1 e2 is the list [e1,e1 + i,e1 + 2i,…], where the increment, i, is e2 − e1. The increment may be zero or negative. If the increment is zero, all the list elements are the same.
  • The sequence enumFromTo e1 e3 is the list [e1,e1 + 1,e1 + 2,…e3]. The list is empty if e1 > e3.
  • 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.

So, yes, what you said is exactly right.

like image 186
Daniel Wagner Avatar answered Jan 20 '26 18:01

Daniel Wagner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!