What lazyStream represents and a potentially endless list. Since SML is an eager , this needs to be done in a slightly circular way.
First, let's see how regular lists work:
datatype 'a list = [] | :: of 'a * 'a list
The ends consist of two parts:
- First item in list
- Rest of the list
On a lazy list, this is pretty similar.
datatype 'a Stream = Nil | Cons of 'a * (unit -> 'a Stream)
Here the cons consist of the following:
- First item in list
- A function that returns the rest of the list when evaluated on
()
So you can see that the principle is almost the same, although it is more difficult to work with.
Take a look at the list of examples:
fun succ n = Cons (n, fn () => succ (n+1))
val naturals = succ 0
What does it give? Let's look at it.
naturals succ 0, , , Cons(0, fn () => succ 1). , 0.
. fn () => succ 1, Cons, (), succ 1, , , Cons(1, fn () => succ 2). , 1.
, , [0, 1, 2, ...].
,
val firstnats = take 10 naturals;
, .