Import Upstream version 20180207
[hcoop/debian/mlton.git] / lib / mlton / env / finite-function.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 *
4 * MLton is released under a BSD-style license.
5 * See the file MLton-LICENSE for details.
6 *)
7(*-------------------------------------------------------------------*)
8(* Env *)
9(*-------------------------------------------------------------------*)
10
11functor Env(D: T): ENV =
12struct
13
14structure D = D
15structure L = List
16
17datatype 'a t = T of (D.t * 'a) L.t
18
19fun empty() = T(L.empty())
20
21fun isEmpty(T l) = L.isEmpty l
22
23fun equal d (d', _) = D.equals(d, d')
24
25fun singleton dr = T(L.single dr)
26
27fun add(T l, d, r) = T((d, r) :: (L.maybeRemoveFirst(l, equal d)))
28
29fun peek(T l, d) =
30 case L.keepFirst(l, equal d) of
31 NONE => NONE
32 | SOME (_, r) => SOME r
33
34fun lookup ed = case peek ed of
35 SOME r => r
36 | NONE => Error.error "Env.lookup"
37
38fun dom(T l) = L.map(l, #1)
39
40fun range(T l) = L.map(l, #2)
41
42fun remove(T ps, d) = T(L.removeFirst(ps, equal d))
43
44fun foldl(T l, b, f) = L.foldl(l, b, fn (b, (d, r)) => f(b, d, r))
45
46fun e + e' = foldl(e', e, add)
47
48fun foreach(T ps, f) = L.foreach(ps, f)
49
50fun multiExtend(env, [], []) = env
51 | multiExtend(env, d :: ds, r :: rs) = multiExtend(extend(env, d, r), ds, rs)
52 | multiExtend _ = Error.error "Env.multiExtend"
53
54fun merge(e as T p, e' as T p', f) =
55 let val leftAndBoth = L.map(p, fn (d, r) =>
56 case peek(e', d) of
57 NONE => (d, r)
58 | SOME r' => (d, f(r, r')))
59 val right = L.keepAll(p',
60 fn (d, _) =>
61 case peek(e, d) of
62 NONE => true
63 | SOME _ => false)
64 in T(leftAndBoth @ right)
65 end
66
67fun output(T ps, outputR, out) =
68 let val print = Out.outputc out
69 fun outputDR((d, r), out) = (D.output(d, out) ;
70 print "->" ;
71 outputR(r, out))
72 in (print "[" ;
73 L.output(ps, ", ", outputDR, out) ;
74 print "]")
75 end
76
77end