open TextIO open Promise fun build f x = let val p = promise() in concur(fn() => f(x,p)) ; future p end fun continue x p = let val p' = promise() in fulfill(p, x::future p') ; p' end fun finish p = fulfill(p, nil) fun plus xsys = build plus' xsys and plus'((x::xs, y::ys), p) = plus'((xs,ys), continue (x+y) p) | plus'( _, p) = finish p fun zip xsys = build zip' xsys and zip'((x::xs, ys), p) = zip'((ys,xs), continue x p) | zip'( _, p) = finish p fun map f xs = build (map' f) xs and map' f (x::xs, p) = map' f (xs, continue (f x) p) | map' f ( nil, p) = finish p fun main() = let val p1 = promise() val p2 = promise() val A = future p1 val B = future p2 val AplusB = plus(A, B) val AzipB = zip(A, B) val AtoChar = map (str o chr) A val Bdiv10 = map (fn n => real n / 10.0) B in Tools.inspect {A, B, AplusB, AzipB, AtoChar, Bdiv10} ; loop(p1,p2) ; OS.Process.exit(OS.Process.success) end and loop pp = ( print "Enter \"k n\" to put number n on stream k (k=1,2)\n" ; loop' pp ) and loop'(p1,p2) = case (print "> "; inputLine stdIn) of "" => () | "\n" => loop'(p1,p2) | s => case String.tokens Char.isSpace s of non [_,_] => loop(p1,p2) | [s1,s2] => case (Int.fromString s1, Int.fromString s2) of non (SOME(1|2), SOME _) => loop(p1,p2) | (SOME k, SOME n) => let val p' = promise() in if k = 1 then (fulfill(p1, n :: future p') ; loop'(p',p2)) else (fulfill(p2, n :: future p') ; loop'(p1,p')) end val _ = main()