Remember that "foo" is just syntactic sugar for 'f':'o':'o':[] .
That is, String is just an alias for [Char] , which is just a linked list of characters.
When client code consumes a linked list, it decomposes it back into the head and tail (for example, x:xs ), does something with the head (if desired), and then recurses for the tail.
When your code creates a linked list, due to a lazy evaluation, all it needs to do is return thunk or promise that it will return the linked list when asked. When the head is dereferenced, it is provided on demand, and the tail remains as a promise for the rest of the list.
It should be easy to see that until the list is copied or otherwise saved, each thunk will be used once and then discarded, so that the total storage space is constant.
Many strict languages ββset up a mechanism (often called a generator) for creating the same kind of lazy list, but with a lazy rating, such functions appear βfor freeβ as part of the language - in fact, all Haskell lists are generators!
source share