Repeat is defined as follows:
repeat :: a -> [a]
repeat x = xs where xs = x:xs
Is there any reason that the following isn't used?
repeat :: a -> [a]
repeat x = x : repeat x
(Obviously there are many equivalent definitions for many Prelude functions, but my latter description just feels much more obvious. I wonder if there's a performance or style reason for the way it is.)
It is for performance and space complexity reasons.
The first version of the code uses explicit sharing; it basically looks like a one-element circular linked list in memory (the xs
in the code is a list node that has x
as value and its tail points to the very same list node). When you evaluate more and more elements of the list it will just take the same node repeatedly.
In contrast, the second version creates a list that actually grows in memory as it is evaluated, because different invocations of repeat x
are always recomputed (and not memoized). There will be always yet another unevaluated thunk at end of the generated list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With