-
Notifications
You must be signed in to change notification settings - Fork 1
/
map-util.sml
66 lines (45 loc) · 2.43 KB
/
map-util.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
functor MapUtilFn (M : ORD_MAP) = struct
fun restrict ks m = foldl (fn (k, acc) =>
case M.find (m, k) of
SOME v => M.insert (acc, k, v)
| NONE => acc
) M.empty (Util.dedup (Util.isEqual o M.Key.compare) ks)
fun str_map (fk, fv) = Util.surround "{" "}" o Util.join ", " o List.map (fn (k, v) => Util.sprintf "$ => $" [fk k, fv v]) o M.listItemsi
fun domain m = List.map Util.fst (M.listItemsi m)
fun is_sub_domain m m' = List.all (fn k => Option.isSome (M.find (m', k))) (domain m)
fun is_same_domain m m' = M.numItems m = M.numItems m' andalso is_sub_domain m m'
fun all f m = List.all f (M.listItems m)
fun alli f m = List.all f (M.listItemsi m)
fun equal eq m m' =
is_same_domain m m' andalso alli (fn (k, v) => eq v (Option.valOf (M.find (m', k)))) m
fun check_equal err f m m' =
if not (is_same_domain m m') then err ()
else
M.intersectWith f (m, m')
fun addList (m, kvs) = foldl (fn ((k, v), m) => M.insert (m, k, v)) m kvs
fun fromList kvs = addList (M.empty, kvs)
fun add_multi ((k, v), m) =
let
val vs = Util.default [] (M.find (m, k))
in
M.insert (m, k, v :: vs)
end
fun addList_multi (m, kvs) = foldl add_multi m kvs
fun fromList_multi kvs = addList_multi (M.empty, kvs)
val to_map = fromList
fun foldli' f = M.foldli (fn (k, v, acc) => f ((k, v), acc))
fun delete (m, k) = Util.fst (M.remove (m, k)) handle NotFound => m
fun enumerate c : ((M.Key.ord_key * 'value), 'result) Enum.enum = fn f => (fn init => foldli' f init c)
fun remove_many (m : 'a M.map) (ks : (M.Key.ord_key, 'a M.map) Enum.enum) : 'a M.map = ks (fn (k, m) => delete (m, k)) m
fun find_many g ks = List.mapPartial (fn k => Option.map (Util.attach_fst k) (M.find (g, k))) ks
fun single a = M.insert' (a, M.empty)
fun must_find m k = Util.assert_SOME (M.find (m, k))
fun sub m m' = M.filteri (fn (k, _) => Util.isNone (M.find (m', k))) m
fun union m m' = M.unionWith Util.snd (m, m')
end
structure IntBinaryMapUtil = MapUtilFn (IntBinaryMap)
structure StringBinaryMapUtil = MapUtilFn (StringBinaryMap)
structure IMap = IntBinaryMap
structure SMap = StringBinaryMap
structure IMapU = IntBinaryMapUtil
structure SMapU = StringBinaryMapUtil