|
|
1.1 root 1: (* stream.sml *)
2:
3: (* Streams as a structure *)
4: (* The type is named Stream to avoid conflict with the i/o type stream *)
5:
6: signature STREAM = sig
7: type 'a Stream
8: val lazyCons: (unit -> '1a * '1a Stream) -> '1a Stream
9: and cons: '1a * '1a Stream -> '1a Stream
10: and head: 'a Stream -> 'a
11: and tail: 'a Stream -> 'a Stream
12: and suffix : int -> 'a Stream -> 'a list
13: and lazyMap : ('1a -> '1b) -> '1a Stream -> '1b Stream
14: end
15:
16: structure Stream : STREAM = struct
17: datatype 'a Stream = mkstream of 'a str ref
18: and 'a str = SOLID of 'a * 'a Stream
19: | SUSPENDED of unit -> ('a * 'a Stream);
20: fun solidify(mkstream(ref(SOLID p))) = p
21: | solidify(mkstream(s as ref(SUSPENDED f))) =
22: let val p = f() in (s := SOLID p; p) end
23: fun lazyCons(f) = mkstream(ref(SUSPENDED f))
24: and cons(x,ss) = mkstream(ref(SOLID(x,ss)))
25: and head s = let val (hd,_) = solidify s in hd end
26: and tail s = let val (_,tl) = solidify s in tl end
27: and suffix 0 s = nil
28: | suffix n s = (head s)::(suffix (n-1) (tail s))
29: fun lazyMap f s =
30: let fun g (mkstream(ref(SOLID(x, s)))) = lazyCons(fn () => (f x, g s))
31: | g (s) = lazyCons
32: (fn () => let val (x, s') = solidify s in (f x, g s') end)
33: in lazyCons(fn () => solidify(g s))
34: end
35: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.