Reputation: 2574
Most of other language use call-by-value. Haskell use call-by-name (lazy evaluation), I'm wonder how does it runs and I think it will be better compare with call-by-value.
Take a example with the question,
the repeat' function defined as this:
repeat' :: a -> [a]
repeat' x = x:repeat' x
use repeat' 3
will get a unlimited list of 3,
ghci> repeat' 3
will generate 3 continuous,
but take 5 (repeat' 3)
will just get [3,3,3,3,3]
.
how does the haskell know end with fifth recursion inner repeat'
function? Besides, I don't think it's a matter of take
.
When the code be executed which stage it difference with call-by-value?
thanks
Upvotes: 1
Views: 95
Reputation: 532053
You get an unlimited list of 3s because typing repeat' 3
in an interactive session essentially calls show (repeat' 3)
, and show
tries to iterate over the entire return value of repeat' 3
. take
, on the other hand, only tries to get a finite number of elements from the list. Here's a definition from the Prelude:
take n _ | n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n-1) xs
Compare the definition of repeat'
, repeat' x = x:repeat' x
with the pattern matched by take. When you call take 5 (repeat' 3)
, the last pattern applies, so it becomes take 5 (3:repeat' 3) = 3 : take 4 (repeat' 3)
. Due to lazy evaluation, repeat'
is only evaluated as much as necessary at any given step, which in this case means extracting the first element to match the pattern x:xs
. Thus, take
builds up a list of 5 3's, terminating when take 0 (repeat' 3)
matches and the recursion terminates, ignoring the unevaluated call to repeat'
to return an empty list.
Upvotes: 2