Backport from sid to buster
[hcoop/debian/mlton.git] / lib / mlton / basic / env.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
8functor Env (S: ENV_STRUCTS): ENV =
9struct
10
11open S
12
13datatype 'a t = T of (Domain.t * 'a) List.t
14
15fun size (T l) = List.length l
16
17fun domain (T drs) = List.revMap (drs, #1)
18
19val fromList = T
20fun toList (T l) = l
21
22fun empty () = T []
23
24fun single (d, r) = T [(d, r)]
25
26fun isEmpty (T l) = List.isEmpty l
27
28fun singleton dr = T [dr]
29
30fun new (ds, f) = T (List.map (ds, fn d => (d, f d)))
31
32fun map (T drs, f) = T (List.map (drs, fn (d, r) => (d, f r)))
33fun mapi (T drs, f) = T (List.map (drs, fn (d, r) => (d, f (d, r))))
34
35fun fold (T drs, b, f) = List.fold (drs, b, fn ((_, r), b) => f (r, b))
36fun foldi (T drs, b, f) = List.fold (drs, b, fn ((d, r), b) => f (d, r, b))
37
38fun equal d (d', _) = Domain.equals (d, d')
39
40fun remove (T drs, d) = T (List.remove (drs, equal d))
41
42fun extend (T drs, d, r) =
43 T (List.cons ((d, r), List.remove (drs, equal d)))
44
45fun env + (T l) = List.fold (l, env, fn ((d, r), env) => extend (env, d, r))
46
47fun plus es = List.fold (es, empty (), fn (e, accum) => accum + e)
48
49fun peek (T l, d) =
50 case List.peek (l, equal d) of
51 NONE => NONE
52 | SOME (_, r) => SOME r
53fun lookup (env, d) = case peek (env, d) of
54 SOME r => r
55 | NONE => (Layout.output (Domain.layout d, Out.error) ;
56 Out.newline Out.error ;
57 Error.bug "Env.lookup")
58
59fun restrict (env, ds) = new (ds, fn d => lookup (env, d))
60
61fun multiExtend (env, ds, rs) =
62 case (ds, rs) of
63 ([], []) => env
64 | (d :: ds, r :: rs) => multiExtend (extend (env, d, r), ds, rs)
65 | _ => Error.bug "Env.multiExtend"
66
67fun foreach (e, f) = List.foreach (toList e, f o #2)
68fun foreachi (e, f) = List.foreach (toList e, f)
69
70fun forall (e, f) = List.forall (toList e, f o #2)
71fun foralli (e, f) = List.forall (toList e, f)
72
73fun equals rangeEqual (e1, e2) =
74 size e1 = size e2
75 andalso foralli (e1, fn (d, r) =>
76 case peek (e2, d) of
77 NONE => false
78 | SOME r' => rangeEqual (r, r'))
79
80fun layout layoutR (T ps) =
81 let open Layout
82 in seq [str "[",
83 align (List.map (ps, fn (d, r) =>
84 seq [Domain.layout d, str " -> ", layoutR r])),
85 str"]"]
86 end
87
88fun maybeLayout (name, layoutR) env =
89 if isEmpty env then Layout.empty
90 else let open Layout
91 in seq [str name, str " = ", layout layoutR env]
92 end
93
94end
95
96functor PolyEnv (S: ENV_STRUCTS): ENV = Env (S)