forked from standardml/cmlib
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdict.sml
executable file
·102 lines (86 loc) · 2.63 KB
/
dict.sml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
functor DictFun (D : PRE_DICT)
:>
DICT
where type key = D.key
=
struct
type key = D.key
type 'a dict = (int * 'a D.dict)
fun size (n, _) = n
exception Absent = D.Absent
val empty = (0, D.empty)
fun singleton key datum = (1, D.singleton key datum)
fun insert (n, d) key datum =
let
val (d', present) = D.insert' d key datum
val n' = if present then n else n+1
in
(n', d')
end
fun insert' (n, d) key datum =
let
val (d', present) = D.insert' d key datum
val n' = if present then n else n+1
in
((n', d'), present)
end
fun remove (n, d) key =
let
val (d', present) = D.remove' d key
val n' = if present then n-1 else n
in
(n', d')
end
fun remove' (n, d) key =
let
val (d', present) = D.remove' d key
val n' = if present then n-1 else n
in
((n', d'), present)
end
fun operate' (n, d) key absentf presentf =
let
val (old, new, d') = D.operate' d key absentf presentf
val n' =
(case (old, new) of
(NONE, NONE) => n
| (SOME _, NONE) => n-1
| (NONE, SOME _) => n+1
| (SOME _, SOME _) => n)
in
(old, new, (n', d'))
end
fun operate dict key absentf presentf =
let
val (x, y, d) = operate' dict key (SOME o absentf) (SOME o presentf)
in
(x, valOf y, d)
end
fun insertMerge dict key x f =
#3 (operate' dict key (fn () => SOME x) (SOME o f))
fun union (dict1 as (n1, d1)) (dict2 as (n2, d2)) f =
if n1 <= n2 then
D.foldl
(fn (key, datum, dict) =>
insertMerge dict key datum
(fn datum' => f (key, datum, datum')))
dict2
d1
else
D.foldl
(fn (key, datum, dict) =>
insertMerge dict key datum
(fn datum' => f (key, datum', datum)))
dict1
d2
fun find (_, d) key = D.find d key
fun lookup (_, d) key = D.lookup d key
fun isEmpty (_, d) = D.isEmpty d
fun member (_, d) key = D.member d key
fun toList (_, d) = D.toList d
fun domain (_, d) = D.domain d
fun map f (n, d) = (n, D.map f d)
fun foldl f x (_, d) = D.foldl f x d
fun foldr f x (_, d) = D.foldr f x d
fun app f (_, d) = D.app f d
end