(* 15-210 Parallel and Sequential Data Structures and Algorithms *)
(* Lecture 25, Fall 2022 *)
(* Dec 5, 2022 *)
(* Live-coded in lecture *)
signature FUTURE =
sig
type 'a t (* abstract *)
val future : (unit -> 'a) -> 'a t
val touch : 'a t -> 'a
end
structure FutureVal :> FUTURE =
struct
type 'a t = 'a
fun future f = f ()
fun touch p = p
end (* structure FutureVal *)
structure FutureName :> FUTURE =
struct
type 'a t = unit -> 'a
fun future f = f
fun touch p = p ()
end (* structure FutureName *)
structure FutureNeed :> FUTURE =
struct
datatype 'a result = VAL of 'a | SUSP of unit -> 'a
type 'a t = ('a result) ref
fun future f = ref (SUSP f)
fun touch p = case !p of
VAL v => v
| SUSP f => let val v = f ()
val () = p := VAL v
in v end
end (* structure FutureNeed *)
structure Fut = FutureNeed
datatype 'a stream = Nil | Cons of 'a * ('a stream) Fut.t
(* producer/consumer *)
fun producer 0 = Nil
| producer n = Cons (n, Fut.future (fn () => producer (n-1)))
fun consumer sum Nil = sum
| consumer sum (Cons (n, p)) = consumer (sum+n) (Fut.touch p)
(* val ex1 = consumer 0 (producer 3) *)
val ex1 = let val p = Fut.future (fn () => producer 3)
in consumer 0 (Fut.touch p) end
datatype bit = B0 | B1
fun neg B0 = B1
| neg B1 = B0
fun fromList nil = Nil
| fromList (b::bs) = Cons(b, Fut.future (fn () => fromList bs))
fun negate Nil = Nil
| negate (Cons(b, p)) = Cons (neg b, Fut.future (fn () => negate (Fut.touch p)))
fun toList Nil = nil
| toList (Cons(b, p)) = b::toList (Fut.touch p)
val ex2 = toList (negate (fromList [B0,B1,B1,B0,B0]))
Table of Content