Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / basic / promise.sml
CommitLineData
7f918cf1
CE
1(* Copyright (C) 2017 Matthew Fluet.
2 * Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9structure Promise: PROMISE =
10struct
11
12datatype 'a t = T of 'a state ref
13and 'a state =
14 Unevaluated of unit -> 'a
15 | Evaluating
16 | Evaluated of 'a
17
18fun layout l (T r) =
19 let
20 open Layout
21 in
22 case !r of
23 Unevaluated _ => str "Unevaluated"
24 | Evaluating => str "Evaluating"
25 | Evaluated x => seq [str "Evaluated ", l x]
26 end
27
28fun delay th = T (ref (Unevaluated th))
29
30fun reset (T r, th) =
31 case !r of
32 Evaluating => Error.bug "Promise.reset"
33 | _ => r := Unevaluated th
34
35exception Force
36fun force (T r) =
37 case !r of
38 Evaluated x => x
39 | Unevaluated th =>
40 (let
41 val _ = r := Evaluating
42 val x = th ()
43 val _ = r := Evaluated x
44 in
45 x
46 end handle exn => (r := Unevaluated th; raise exn))
47 | Evaluating => raise Force
48
49fun lazy th =
50 let val p = delay th
51 in fn () => force p
52 end
53
54fun isUnevaluated (T r) =
55 case !r of
56 Unevaluated _ => true
57 | _ => false
58
59end