3

Could someone explain the behaviour of this little piece of code with the following input: [[1,2],[3,4]]?

infiniteList ls = let v = ls ++ v
                  in concat v

The result is an infinite list but I don't realise why. I've understood that the trick is in:

ls ++ v

But how exactly work the let since we do not define the initial value for the variable v?

Will Ness
  • 70,110
  • 9
  • 98
  • 181
BigMeister
  • 361
  • 2
  • 11

1 Answers1

7

To evaluate v, just replace it with its definition:

v = ls ++ v
  = ls ++ ls ++ v
  = ls ++ ls ++ ls ++ v
  = ls ++ ls ++ ls ++ ls ++ v
  = ls ++ ls ++ ls ++ ls ++ ls ++ v
  = ls ++ ls ++ ls ++ ls ++ ls ++ ls ++ v

Clearly this will never end.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • And the evaluation happens when the function concat is called, right? – BigMeister Jan 07 '18 at 15:51
  • 2
    @BigMeister Because Haskell is lazy, this evaluation occurs only when it is absolutely necessary, such as when you print out the result of calling `infiniteList`. – Code-Apprentice Jan 07 '18 at 15:53
  • 5
    Don't think of `ls ++ v` as constructing a value that is then assigned to `v`; rather, it is just a *rule* for evaluating `v`. "When you see `v`, replace it with `ls ++ v`." Whether then recursive occurrence of `v` needs to be evaluated depends on the consumer of the original `v`. – chepner Jan 07 '18 at 15:56
  • Yes, I got it now! I was misunderstanding the meaning of the let but now It is clear. Thank you both! – BigMeister Jan 07 '18 at 16:03