datatype 'a stream = Cons of 'a * (unit -> 'a stream) fun force s = s () fun chop 0 _ = [] | chop n (Cons (x, s)) = x :: chop (n-1) (force s) fun repeat 0 x s = force s | repeat n x s = Cons (x, fn () => repeat (n-1) x s) fun decode (Cons ((x, n), s)) = repeat n x (fn () => decode (force s)) fun encode (Cons (x, s)) = let fun accumulate x n (Cons (y, s)) = if x = y then accumulate x (n+1) (force s) else Cons ((x, n), fn () => accumulate y 1 (force s)) in accumulate x 1 (force s) end