|
|
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.