/* * Copyright 2017 Liam Palmer, Esben Bjerre * * Use of this source code is governed by the Apache 2.0 license * that can be found in the LICENSE.md file. */pubmod Map {////// The Map type.////// A map is currently represented internally as a red-black tree.///pubenumMap[k, v] {case Map(RedBlackTree[k, v]) }instanceEq[Map[k, v]] withEq[k], Eq[v] {pubdefeq(m1: Map[k, v], m2: Map[k, v]): Bool =Map.toList(m1) ==Map.toList(m2) }instanceOrder[Map[k, v]] withOrder[k], Order[v] {pubdefcompare(x: Map[k, v], y: Map[k, v]): Comparison =Map.toList(x) <=>Map.toList(y) }instanceFormattable[Map[k, v]] withFormattable[k], Formattable[v] {typeAef = Formattable.Aef[k] + Formattable.Aef[v]pubdefformat(x: Map[k, v]): RichString \ (Formattable.Aef[k] + Formattable.Aef[v]) =letpairs = Map.toList(x) |> List.map(match (k, v) -> Formattable.format(k) +RichString.fromString(" => ") +Formattable.format(v));RichString.fromString("Map#{") +RichString.joinWith(identity, RichString.fromString(", "), pairs) +RichString.fromString("}") }instanceToString[Map[k, v]] withToString[k], ToString[v] {pubdeftoString(m: Map[k, v]): String = Map.toString(m) }instanceHash[Map[k, v]] withHash[k], Hash[v] {pubdefhash(m: Map[k, v]): Int32 =Map.foldLeftWithKey((acc, k, v) -> acc`Hash.combine`Hash.hash(k) `Hash.combine`Hash.hash(v), Hash.magic(), m) }instanceIndexable[Map[k, v]] withOrder[k] {typeIdx = ktypeElm = vtypeAef = KeyNotFoundpubdefget(t: Map[k, v], i: k): v \ KeyNotFound = matchMap.get(i, t) {case Some(v) => vcase None => KeyNotFound.keyNotFound("key not found") } }instanceFunctor[Map[k]] {pubdefmap(f: v1 -> v2 \ ef, m: Map[k, v1]): Map[k, v2] \ ef = Map.map(f, m) }instanceFoldable[Map[k]] {pubdeffoldLeft(f: (b, v) -> b \ ef, s: b, m: Map[k, v]): b \ ef = Map.foldLeft(f, s, m)pubdeffoldRight(f: (v, b) -> b \ ef, s: b, m: Map[k, v]): b \ ef = Map.foldRight(f, s, m) redef isEmpty(m: Map[k, v]): Bool = Map.isEmpty(m) }instanceUnorderedFoldable[Map[k]] {pubdeffoldMap(f: v -> b \ ef, m: Map[k, v]): b \ efwithCommutativeMonoid[b] = Map.foldMap(f, m) redef isEmpty(m: Map[k, v]): Bool = Map.isEmpty(m) redef exists(f: v -> Bool \ ef, m: Map[k, v]): Bool \ ef = Map.exists(_ -> f, m) redef forAll(f: v -> Bool \ ef, m: Map[k, v]): Bool \ ef = Map.forAll(_ -> f, m) }instanceTraversable[Map[k]] {pubdeftraverse(f: a -> m[b] \ ef, t: Map[k, a]): m[Map[k, b]] \ efwithApplicative[m] = Map.traverse(f, t) redef sequence(t: Map[k, m[a]]): m[Map[k, a]] withApplicative[m] = Map.sequence(t) }instanceFilterable[Map[k]] withOrder[k] {pubdeffilterMap(f: a -> Option[b] \ ef, m: Map[k, a]): Map[k, b] \ ef = Map.filterMap(f, m) redef filter(f: a -> Bool \ ef, m: Map[k, a]): Map[k, a] \ ef = Map.filter(f, m) }instanceWitherable[Map[k]] withOrder[k]instanceSemiGroup[Map[k, v]] withOrder[k], SemiGroup[v] {pubdefcombine(x: Map[k, v], y: Map[k, v]): Map[k, v] = Map.unionWith(SemiGroup.combine, x, y) }instanceCommutativeSemiGroup[Map[k, v]] withOrder[k], CommutativeSemiGroup[v]instanceMonoid[Map[k, v]] withOrder[k], Monoid[v] {pubdefempty(): Map[k, v] = Map.empty() }instanceCommutativeMonoid[Map[k, v]] withOrder[k], CommutativeMonoid[v]instanceLowerBound[Map[k, v]] {pubdefminValue(): Map[k, v] = Map.empty() }instancePartialOrder[Map[k, v]] withOrder[k], Eq[v] {pubdeflessEqual(m1: Map[k, v], m2: Map[k, v]): Bool = m1`Map.isSubmapOf`m2 }instanceJoinLattice[Map[k, v]] withOrder[k], Eq[v], JoinLattice[v] {pubdefleastUpperBound(m1: Map[k, v], m2: Map[k, v]): Map[k, v] =Map.unionWith(JoinLattice.leastUpperBound, m1, m2) }instanceMeetLattice[Map[k, v]] withOrder[k], Eq[v], MeetLattice[v] {pubdefgreatestLowerBound(m1: Map[k, v], m2: Map[k, v]): Map[k, v] =Map.intersectionWith(MeetLattice.greatestLowerBound, m1, m2) }instanceIterable[Map[k, v]] {typeElm = (k, v)pubdefiterator(rc: Region[r], m: Map[k, v]): Iterator[(k, v), r, r] \ r = Map.iterator(rc, m) }instanceForEach[Map[k, v]] {typeElm = (k, v)pubdefforEach(f: ((k, v)) -> Unit \ ef, t: Map[k, v]): Unit \ ef = Map.forEach(k -> v -> f((k, v)), t) }////// Returns a string representation of the given map `m`.///pubdeftoString(m: Map[k, v]): StringwithToString[k], ToString[v] = regionrc {"Map#{"+ (Map.iterator(rc, m) |> Iterator.map(match (k, v) -> "${k} => ${v}") |> Iterator.join(", ")) +"}" }////// Determines whether to use parallel evaluation.////// By default we only enable parallel evaluation if the map has a certain size.///defuseParallelEvaluation(m: Map[k, v]): Bool =let Map(t) = m;letminSize = Int32.pow(base = 2, RedBlackTree.blackHeight(t));minSize>=1024////// Returns the number of keys in `m`.///pubdefsize(m: Map[k, v]): Int32 =let Map(xs) = m;RedBlackTree.size(xs)////// Returns the empty map.////// `Map#{}` is syntactic sugar for `empty` (`Map#{} == empty()`).///pubdefempty(): Map[k, v] = Map(RedBlackTree.empty())////// Returns the singleton map where key `k` is mapped to value `v`.////// `Map#{k => v}` is syntactic sugar for `singleton` (`Map#{k => v} = singleton(k, v)`).///pubdefsingleton(k: k, v: v): Map[k, v] withOrder[k] = insert(k, v, empty())////// Returns `true` if and only if `m` is the empty map, i.e. `Map(Nil)`.///pubdefisEmpty(m: Map[k, v]): Bool =let Map(t) = m;RedBlackTree.isEmpty(t)////// Returns `true` if and only if `m` is a non-empty map.///pubdefnonEmpty(m: Map[k, v]): Bool = notisEmpty(m)////// Returns `Some(v)` if `k => v` is in `m`.////// Otherwise returns `None`.///pubdefget(k: k, m: Map[k, v]): Option[v] withOrder[k] =let Map(t) = m;RedBlackTree.get(k, t)////// Returns `v` if `k => v` is in `m`.////// Otherwise, returns `d`.///pubdefgetWithDefault(k: k, d: v, m: Map[k, v]): vwithOrder[k] = Option.getWithDefault(d, get(k, m))////// Returns the value associated with key `k` in map `m`.////// Aborts if the key is not present.///pubdefgetOrAbort(k: k, m: Map[k, v]): v \ AbortwithOrder[k] =matchMap.get(k, m) {case None => Abort.abortWithTrace("Map.getOrAbort(): key not found")case Some(v) => v }////// Returns `true` if and only if `m` contains the key `k`.///pubdefmemberOf(k: k, m: Map[k, v]): BoolwithOrder[k] =let Map(t) = m;RedBlackTree.memberOf(k, t)////// Optionally finds `k => v` where `k` is the smallest key according to the `Order` instance of `k`.////// Returns `None` if `m` is empty.///pubdefminimumKey(m: Map[k, v]): Option[(k, v)] =let Map(t) = m;RedBlackTree.minimumKey(t)////// Optionally finds `k => v` where `k` is the smallest key according to the given comparator `cmp`.////// Returns `None` if `m` is empty.////// Purity reflective: Runs in parallel when given a pure function `cmp`.///@ParallelWhenPurepubdefminimumKeyBy(cmp: (k, k) -> Comparison \ ef, m: Map[k, v]): Option[(k, v)] \ ef =defmin() = reduceLeftWithKey((kl, vl, kr, vr) -> if (cmp(kl, kr) == Comparison.LessThan) (kl, vl) else (kr, vr), m);matchpurityOf2(cmp) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))leth = (kl, _, kr, _) -> g(kl, kr);let Map(t) = m;RedBlackTree.parMinimumBy(h, t)elsemin()case Purity2.Impure(_) => min() }////// Optionally finds `k => v` where `v` is the smallest value.////// Returns `None` if `m` is empty.///@ParallelpubdefminimumValue(m: Map[k, v]): Option[(k, v)] withOrder[v] =minimumValueBy((x, y) -> x<=>y, m)////// Optionally finds `k => v` where `v` is the smallest value according to the given comparator `cmp`.////// Returns `None` if `m` is empty.////// Purity reflective: Runs in parallel when given a pure function `cmp`.///@ParallelWhenPurepubdefminimumValueBy(cmp: (v, v) -> Comparison \ ef, m: Map[k, v]): Option[(k, v)] \ ef =defmin() = reduceLeftWithKey((kl, vl, kr, vr) -> if (cmp(vl, vr) == Comparison.LessThan) (kl, vl) else (kr, vr), m);matchpurityOf2(cmp) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))leth = (_, vl, _, vr) -> g(vl, vr);let Map(t) = m;RedBlackTree.parMinimumBy(h, t)elsemin()case Purity2.Impure(_) => min() }////// Optionally finds `k => v` where `k` is the largest key according to the `Order` instance of `k`.////// Returns `None` if `m` is empty.///pubdefmaximumKey(m: Map[k, v]): Option[(k, v)] =let Map(t) = m;RedBlackTree.maximumKey(t)////// Optionally finds `k => v` where `k` is the largest key according to the given comparator `cmp`.////// Returns `None` if `m` is empty.////// Purity reflective: Runs in parallel when given a pure function `cmp`.///@ParallelWhenPurepubdefmaximumKeyBy(cmp: (k, k) -> Comparison \ ef, m: Map[k, v]): Option[(k, v)] \ ef =defmax() = reduceLeftWithKey((kl, vl, kr, vr) -> if (cmp(kl, kr) == Comparison.GreaterThan) (kl, vl) else (kr, vr), m);matchpurityOf2(cmp) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))leth = (kl, _, kr, _) -> g(kl, kr);let Map(t) = m;RedBlackTree.parMaximumBy(h, t)elsemax()case Purity2.Impure(_) => max() }////// Optionally finds `k => v` where `v` is the largest value.////// Returns `None` if `m` is empty.///@ParallelpubdefmaximumValue(m: Map[k, v]): Option[(k, v)] withOrder[v] =maximumValueBy((x, y) -> x<=>y, m)////// Optionally finds `k => v` where `v` is the largest value according to the given comparator `cmp`.////// Returns `None` if `m` is empty.////// Purity reflective: Runs in parallel when given a pure function `cmp`.///@ParallelWhenPurepubdefmaximumValueBy(cmp: (v, v) -> Comparison \ ef, m: Map[k, v]): Option[(k, v)] \ ef =defmax() = reduceLeftWithKey((kl, vl, kr, vr) -> if (cmp(vl, vr) == Comparison.GreaterThan) (kl, vl) else (kr, vr), m);matchpurityOf2(cmp) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))leth = (_, vl, _, vr) -> g(vl, vr);let Map(t) = m;RedBlackTree.parMaximumBy(h, t)elsemax()case Purity2.Impure(_) => max() }////// Returns the keys of `m`.///pubdefkeysOf(m: Map[k, v]): Set[k] withOrder[k] =foldLeftWithKey((acc, k, _) -> Set.insert(k, acc), Set.empty(), m)////// Returns the values of `m`.///pubdefvaluesOf(m: Map[k, v]): List[v] =foldRight((v, acc) -> v :: acc, Nil, m)////// Updates `m` with `k => v`.///pubdefinsert(k: k, v: v, m: Map[k, v]): Map[k, v] withOrder[k] =let Map(t) = m; Map(RedBlackTree.insert(k, v, t))////// Updates `m` with `k => f(v, v1)` if `k => v1` is in `m`.////// Otherwise, updates `m` with `k => v`.///pubdefinsertWith(f: (v, v) -> v \ ef, k: k, v: v, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =insertWithKey((_, v1, v2) -> f(v1, v2), k, v, m)////// Updates `m` with `k => f(k, v, v1)` if `k => v1` is in `m`.////// Otherwise, updates `m` with `k => v`.///pubdefinsertWithKey(f: (k, v, v) -> v \ ef, k: k, v: v, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =let Map(t) = m; Map(RedBlackTree.insertWith(f, k, v, t))////// Updates `m` with `k => f(v)` if `k => v` is in `m`.////// Otherwise, returns `m`.///pubdefadjust(f: v -> v \ ef, k: k, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =adjustWithKey((_, v1) -> f(v1), k, m)////// Updates `m` with `k => f(k, v)` if `k => v` is in `m`. Otherwise, returns `m`.///pubdefadjustWithKey(f: (k, v) -> v \ ef, k: k, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =updateWithKey((k1, v) -> Some(f(k1, v)), k, m)////// Updates `m` with `k => v1` if `k => v` is in `m` and `f(v) = Some(v1)`. Otherwise, returns `m`.///pubdefupdate(f: v -> Option[v] \ ef, k: k, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =updateWithKey((_, v1) -> f(v1), k, m)////// Updates `m` with `k => v1` if `k => v` is in `m` and `f(k, v) = Some(v1)`. Otherwise, returns `m`.///pubdefupdateWithKey(f: (k, v) -> Option[v] \ ef, k: k, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =let Map(t) = m; Map(RedBlackTree.updateWith(f, k, t))////// Removes the mapping `k` from the map `m`.///pubdefremove(k: k, m: Map[k, v]): Map[k, v] withOrder[k] =let Map(t) = m; Map(RedBlackTree.remove(k, t))////// Returns `true` if and only if all mappings in `m1` occur in `m2`.///pubdefisSubmapOf(m1: Map[k, v], m2: Map[k, v]): BoolwithOrder[k], Eq[v] = forAll((k, v) -> get(k, m2) == Some(v), m1)////// Returns `true` if and only if all mappings in `m1` occur in `m2` and `m1 != m2`.///pubdefisProperSubmapOf(m1: Map[k, v], m2: Map[k, v]): BoolwithOrder[k], Eq[v] =size(m1) !=size(m2) andisSubmapOf(m1, m2)////// Alias for `findLeft`.///pubdeffind(f: (k, v) -> Bool \ ef, m: Map[k, v]): Option[(k, v)] \ ef = findLeft(f, m)////// Optionally returns the first mapping of `m` that satisfies the predicate `f` when searching from left to right.///pubdeffindLeft(f: (k, v) -> Bool \ ef, m: Map[k, v]): Option[(k, v)] \ ef =let Map(t) = m;RedBlackTree.findLeft(f, t)////// Optionally returns the first mapping of `m` that satisfies the predicate `f` when searching from right to left.///pubdeffindRight(f: (k, v) -> Bool \ ef, m: Map[k, v]): Option[(k, v)] \ ef =let Map(t) = m;RedBlackTree.findRight(f, t)////// Returns a map of all mappings `k => v` in `m` where `v` satisfies the predicate `f`.///pubdeffilter(f: v -> Bool \ ef, m: Map[k, v]): Map[k, v] \ efwithOrder[k] = filterWithKey((_, v) -> f(v), m)////// Returns a map of all mappings `k => v` in `m` where `(k, v)` satisfies the predicate `f`.///pubdeffilterWithKey(f: (k, v) -> Bool \ ef, m: Map[k, v]): Map[k, v] \ efwithOrder[k] =foldLeftWithKey((acc, k, v) -> if (f(k, v)) insert(k, v, acc) elseacc, empty(), m)////// Returns a map of all mappings `k => v1` in `m` where applying the function `f` to `v` produces/// a `Some(v1)`. Elements that produce `None` are discarded.///pubdeffilterMap(f: a -> Option[b] \ ef, m: Map[k, a]): Map[k, b] \ efwithOrder[k] =letstep = (acc, k, a) -> matchf(a) {case Some(b) => Map.insert(k, b, acc)case None => acc };Map.foldLeftWithKey(step, Map.empty(), m)////// Returns a map of all mappings `k => v1` in `m` where applying the function `f` to `(k, v)` produces/// `Some(v1)`. Elements that produce `None` are discarded.///pubdeffilterMapWithKey(f: (k, a) -> Option[b] \ ef, m: Map[k, a]): Map[k, b] \ efwithOrder[k] =letstep = (acc, k, a) -> matchf(k, a) {case Some(b) => insert(k, b, acc)case None => acc };foldLeftWithKey(step, Map.empty(), m)////// Returns a map with mappings `k => f(v)` for every `k => v` in `m`.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefmap(f: v1 -> v2 \ ef, m: Map[k, v1]): Map[k, v2] \ ef = mapWithKey((_, v) -> f(v), m)////// Returns a map with mappings `k => f(k, v)` for every `k => v` in `m`.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefmapWithKey(f: (k, v1) -> v2 \ ef, m: Map[k, v1]): Map[k, v2] \ ef =let Map(t) = m; Map(RedBlackTree.mapWithKey(f, t))////// Alias for `foldLeftWithKey`.///pubdeffoldWithKey(f: (b, k, v) -> b \ ef, s: b, m: Map[k, v]): b \ ef = foldLeftWithKey(f, s, m)////// Applies `f` to a start value `s` and all values in `m` going from left to right.////// That is, the result is of the form: `f(...f(f(s, v1), v2)..., vn)`.///pubdeffoldLeft(f: (b, v) -> b \ ef, s: b, m: Map[k, v]): b \ ef =foldLeftWithKey((acc, _, v) -> f(acc, v), s, m)////// Applies `f` to a start value `s` and all key-value pairs in `m` going from left to right.////// That is, the result is of the form: `f(...f(f(s, k1, v1), k2, v2)..., vn)`.///pubdeffoldLeftWithKey(f: (b, k, v) -> b \ ef, s: b, m: Map[k, v]): b \ ef =let Map(xs) = m;RedBlackTree.foldLeft(f, s, xs)////// Applies `f` to a start value `s` and all values in `m` going from right to left.////// That is, the result is of the form: `f(v1, ...f(vn-1, f(vn, s)))`.///pubdeffoldRight(f: (v, b) -> b \ ef, s: b, m: Map[k, v]): b \ ef =foldRightWithKey((_, v, acc) -> f(v, acc), s, m)////// Applies `f` to a start value `s` and all key-value pairs in `m` going from right to left.////// That is, the result is of the form: `f(k1, v1, ...f(kn-1, vn-1, f(kn, vn, s)))`.///pubdeffoldRightWithKey(f: (k, v, b) -> b \ ef, s: b, m: Map[k, v]): b \ ef =let Map(t) = m;RedBlackTree.foldRight(f, s, t)////// Returns the result of mapping each key-value pair and combining the results.///pubdeffoldMapWithKey(f: (k, v) -> b \ ef, m: Map[k, v]): b \ efwithMonoid[b] =foldLeftWithKey((acc, k, v) -> Monoid.combine(acc, f(k, v)), Monoid.empty(), m)////// Returns the result of mapping each value and combining the results.///pubdeffoldMap(f: v -> b \ ef, m: Map[k, v]): b \ efwithMonoid[b] =foldMapWithKey(_ -> f, m)////// Applies `f` to all values in `m` going from left to right until a single value `v` is obtained. Returns `Some(v)`.////// That is, the result is of the form: `Some(f(...f(f(v1, v2), v3)..., vn))`////// Returns `None` if `m` is the empty map.///pubdefreduceLeft(f: (v, v) -> v \ ef, m: Map[k, v]): Option[v] \ ef =reduceLeftWithKey((k, v1, _, v2) -> (k, f(v1, v2)), m) |> Option.map(snd)////// Applies `f` to all mappings in `m` going from left to right until a single mapping `(k, v)` is obtained. Returns `Some((k, v))`.////// That is, the result is of the form: `Some(f(...f(f(k1, v1, k2, v2), k3, v3)..., kn, vn))`////// Returns `None` if `m` is the empty map.///pubdefreduceLeftWithKey(f: (k, v, k, v) -> (k, v) \ ef, m: Map[k, v]): Option[(k, v)] \ ef =let Map(t) = m;RedBlackTree.reduceLeft(f, t)////// Applies `f` to all values in `m` going from right to left until a single value `v` is obtained. Returns `Some(v)`.////// That is, the result is of the form: `Some(f(v1, ...f(vn-2, f(vn-1, vn))...))`////// Returns `None` if `m` is the empty map.///pubdefreduceRight(f: (v, v) -> v \ ef, m: Map[k, v]): Option[v] \ ef =reduceRightWithKey((k, v1, _, v2) -> (k, f(v1, v2)), m) |> Option.map(snd)////// Applies `f` to all mappings in `m` going from right to left until a single mapping `(k, v)` is obtained. Returns `Some((k, v))`.////// That is, the result is of the form: `Some(f(k1, v1, ...f(kn-2, vn-2, f(kn-1, vn-1, kn, vn))...))`////// Returns `None` if `m` is the empty map.///pubdefreduceRightWithKey(f: (k, v, k, v) -> (k, v) \ ef, m: Map[k, v]): Option[(k, v)] \ ef =let Map(t) = m;RedBlackTree.reduceRight(f, t)////// Returns the number of mappings `k => v` in `m` that satisfy the predicate `f`.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefcount(f: (k, v) -> Bool \ ef, m: Map[k, v]): Int32 \ ef =defc() = foldLeftWithKey((b, k, v) -> if (f(k, v)) b+1elseb, 0, m);matchpurityOf2(f) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))let Map(t) = m;RedBlackTree.parCount(g, t)elsec()case Purity2.Impure(_) => c() }////// Returns the sum of all key-value pairs `k => v` in the map `m` according to the function `f`.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefsumWith(f: (k, v) -> Int32 \ ef, m: Map[k, v]): Int32 \ ef =let Map(t) = m;defsw() = RedBlackTree.sumWith(f, t);matchpurityOf2(f) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))RedBlackTree.parSumWith(g, t)elsesw()case Purity2.Impure(_) => sw() }////// Returns `true` if and only if at least one mapping in `m` satisfies the predicate `f`.////// Returns `false` if `m` is the empty map.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefexists(f: (k, v) -> Bool \ ef, m: Map[k, v]): Bool \ ef =let Map(t) = m;defe() = RedBlackTree.exists(f, t);matchpurityOf2(f) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))RedBlackTree.parExists(g, t)elsee()case Purity2.Impure(_) => e() }////// Returns `true` if and only if all mappings in `m` satisfy the predicate `f`.////// Returns `true` if `m` is the empty map.////// Purity reflective: Runs in parallel when given a pure function `f`.///@ParallelWhenPurepubdefforAll(f: (k, v) -> Bool \ ef, m: Map[k, v]): Bool \ ef =let Map(t) = m;deffa() = RedBlackTree.forAll(f, t);matchpurityOf2(f) {case Purity2.Pure(g) =>if (useParallelEvaluation(m))RedBlackTree.parForAll(g, t)elsefa()case Purity2.Impure(_) => fa() }////// Returns the left-biased union of `m1` and `m2`.////// That is, key collisions are resolved by taking the mapping from `m1`.///pubdefunion(m1: Map[k, v], m2: Map[k, v]): Map[k, v] withOrder[k] =unionWithKey((_, v1, _) -> v1, m1, m2)////// Returns the union of `m1` and `m2` where key collisions are resolved with the merge function `f`.///pubdefunionWith(f: (v, v) -> v \ ef, m1: Map[k, v], m2: Map[k, v]): Map[k, v] \ efwithOrder[k] =unionWithKey((_, v1, v2) -> f(v1, v2), m1, m2)////// Returns the union of `m1` and `m2` where key collisions are resolved with the merge function `f`, taking both the key and values.///pubdefunionWithKey(f: (k, v, v) -> v \ ef, m1: Map[k, v], m2: Map[k, v]): Map[k, v] \ efwithOrder[k] =use RedBlackTree.{blackHeight, foldRight, insertWith};let Map(t1) = m1;let Map(t2) = m2;if (blackHeight(t1) <blackHeight(t2)) Map(foldRight((k, v, acc) -> insertWith(f, k, v, acc), t2, t1))else Map(foldRight((k, v, acc) -> insertWith((_, v1, v2) -> f(k, v2, v1), k, v, acc), t1, t2))////// Returns the left-biased intersection of `m1` and `m2`.////// That is, key collisions are resolved by taking the mapping from `m1`.///pubdefintersection(m1: Map[k, v], m2: Map[k, v]): Map[k, v] withOrder[k] =filterWithKey((k, _) -> memberOf(k, m2), m1)////// Returns the intersection of `m1` and `m2` where key collisions are resolved with the merge function `f`.///pubdefintersectionWith(f: (v1, v2) -> v3 \ ef, m1: Map[k, v1], m2: Map[k, v2]): Map[k, v3] \ efwithOrder[k] =intersectionWithKey((_, v1, v2) -> f(v1, v2), m1, m2)////// Returns the intersection of `m1` and `m2` where key collisions are resolved with the merge function `f`, taking both the key and values.///pubdefintersectionWithKey(f: (k, v1, v2) -> v3 \ ef, m1: Map[k, v1], m2: Map[k, v2]): Map[k, v3] \ efwithOrder[k] =filterMapWithKey((k, v1) -> Option.map(v2 -> f(k, v1, v2), get(k, m2)), m1)////// Returns the difference of `m1` and `m2`, i.e. `m1 - m2`.////// That is, returns the map `m1` with the keys removed that are in `m2`.///pubdefdifference(m1: Map[k, v], m2: Map[k, v]): Map[k, v] withOrder[k] =differenceWithKey((_, _, _) -> None, m1, m2)////// Returns the difference of `m1` and `m2`, i.e. `m1 - m2`.////// When a key `k` is in both `m1` and `m2`, the associated values are passed to the merge function `f`./// If `f` returns `None` the mapping with `k` is thrown away (proper set difference)./// If `f` returns `Some(v)` the mapping `k => v` is included in the result.///pubdefdifferenceWith(f: (v, v) -> Option[v] \ ef, m1: Map[k, v], m2: Map[k, v]): Map[k, v] \ efwithOrder[k] =differenceWithKey((_, v1, v2) -> f(v1, v2), m1, m2)////// Returns the difference of `m1` and `m2`, i.e. `m1 - m2`.////// When a key `k` is in both `m1` and `m2`, `k` and the associated values are passed to the merge function `f`./// If `f` returns `None` the mapping with `k` is thrown away (proper set difference)./// If `f` returns `Some(v)` the mapping `k => v` is included in the result.///pubdefdifferenceWithKey(f: (k, v, v) -> Option[v] \ ef, m1: Map[k, v], m2: Map[k, v]): Map[k, v] \ efwithOrder[k] =letdiff = filterWithKey((k, _) -> notmemberOf(k, m2), m1);letg = (k, v, acc) ->if (memberOf(k, m1))matchget(k, m1) {case Some(v1) =>matchf(k, v1, v) {case None => acccase Some(w) => insert(k, w, acc) }case None => unreachable!() }elseacc;foldRightWithKey(g, diff, m2)////// Returns the inverse map of `m`.////// That is, given a `Map[k, v]` returns a map `Map[v, Set[k]]`/// where every value is mapped to its key(s) in the original map.///pubdefinvert(m: Map[k, v]): Map[v, Set[k]] withOrder[k], Order[v] =letf = (acc, k, v) -> Map.insertWith(Set.union, v, Set#{k}, acc);Map.foldLeftWithKey(f, empty(), m)////// Returns the map `m` as a list of key-value pairs.///pubdeftoList(m: Map[k, v]): List[(k, v)] =foldRightWithKey((k, v, acc) -> (k, v) :: acc, Nil, m)////// Returns the map `m` as an array.///pubdeftoArray(rc: Region[r], m: Map[k, v]): Array[(k, v), r] \ r = matchsize(m) {case 0 => Array#{} @ rccasesz =>leta = Array.empty(rc, sz);forEachWithIndex((i, k, v) -> Array.put((k, v), i, a), m);a }////// Returns the map `m` as a vector.///pubdeftoVector(m: Map[k, v]): Vector[(k, v)] = regionrc {letarr = Array.empty(rc, size(m));forEachWithIndex((i, k, v) -> Array.put((k, v), i, arr), m);Array.toVector(arr) }////// Returns the map `m` as a set of key-value pairs.///pubdeftoSet(m: Map[k, v]): Set[(k, v)] withOrder[k], Order[v] =foldLeftWithKey((acc, k, v) -> Set.insert((k, v), acc), Set.empty(), m)////// Returns the map `m` as a chain of key-value pairs.///pubdeftoChain(m: Map[a, b]): Chain[(a, b)] withOrder[a] =foldLeftWithKey((acc, k, v) -> Chain.snoc(acc, (k, v)), Chain.empty(), m)////// Returns a MultiMap where key `k` is mapped to the singleton set containing `v`.///pubdeftoMultiMap(m: Map[k, v]): MultiMap[k, v] withOrder[k], Order[v] = MultiMap.MultiMap(Map.map(Set.singleton, m))////// Applies `f` to every `(key, value)` of `m`.///pubdefforEach(f: (k, v) -> Unit \ ef, m: Map[k, v]): Unit \ ef =let Map(t) = m;RedBlackTree.forEach(f, t)////// Applies `f` to tuple `(index, key, value)` formed of the keys and values of/// Map `m` and the index of the traversal.///pubdefforEachWithIndex(f: (Int32, k, v) -> Unit \ ef, m: Map[k, v]): Unit \ ef =let Map(t) = m;RedBlackTree.forEachWithIndex(f, t)////// Build a map by applying `f` to the seed value `st`.////// `f` should return `Some(k,v,st1)` to signal a new key-value pair `k` and `v` and a new seed value `st1`.////// `f` should return `None` to signal the end of building the map.///pubdefunfold(f: s -> Option[(k, v, s)] \ ef, st: s): Map[k, v] \ efwithOrder[k] =defloop(sst, m) = matchf(sst) {case None => mcase Some((k, v, st1)) => loop(st1, insert(k, v, m)) };loop(st, empty())////// Build a map by applying the function `next` to `()`. `next` is expected to encapsulate/// a stateful resource such as a file handle that can be iterated.////// `next` should return `Some(k,v)` to signal a new key-value pair `k` and `v`.////// `next` should return `None` to signal the end of building the map.///pubdefunfoldWithIter(next: Unit -> Option[(k, v)] \ ef): Map[k, v] \ efwithOrder[k] =defloop(m) = matchnext() {case None => mcase Some((k, v)) => loop(insert(k, v, m)) };loop(empty())////// Build a map by applying `f` to the initial key-value pair `(k, v)`.////// `f` should return `Some(k1, v1)` to signal a new key-value pair (which also becomes the next input to `f`).////// `f` should return `None` to signal the end of building the map.///pubdefiterate(f: (k, v) -> Option[(k, v)] \ ef, k: k, v: v): Map[k, v] \ efwithOrder[k] =defloop(ck, cv, m) = matchf(ck, cv) {case None => mcase Some((k1, v1)) => loop(k1, v1, insert(k1, v1, m)) };loop(k, v, empty())////// Returns the set of tuples `(k, v)` where `v` is a value in `t` and `k => t`.///pubdefexplode(m: Map[k, t[v]]): Set[(k, v)] \ Foldable.Aef[t] withFoldable[t], Order[k], Order[v] =foldLeftWithKey((acc, k, t) -> Foldable.toSet(t) |> Set.map(e -> (k, e)) |> Set.union(acc), Set.empty(), m)////// Extracts a range of key-value pairs from the map `m`.////// That is, the result is a list of all pairs `(k, v)` where `p(k)` returns `Equal`.///pubdefrangeQuery(p: k -> Comparison \ ef, m: Map[k, v]): List[(k, v)] \ ef =let Map(t) = m;RedBlackTree.rangeQuery(p, (k, v) -> (k, v), t)////// Applies `f` to all key-value pairs `(k, v)` from the map `m` where `p(k)` returns `EqualTo`.///pubdefrangeQueryWith(p: k -> Comparison \ ef1, f: (k, v) -> Unit \ ef2, m: Map[k, v]): Unit \ { ef1, ef2 } =let Map(t) = m;RedBlackTree.rangeQueryWith(p, f, t)////// Returns an iterator over all key-value pairs in `m`.///pubdefiterator(rc: Region[r], m: Map[k, v]): Iterator[(k, v), r, r] \ r =let Map(t) = m;RedBlackTree.iterator(rc, t)////// Returns an iterator over keys in `m`.///pubdefiteratorKeys(rc: Region[r], m: Map[k, v]): Iterator[k, r, r] \ r =iterator(rc, m) |> Iterator.map(fst)////// Returns an iterator over values in `m`.///pubdefiteratorValues(rc: Region[r], m: Map[k, v]): Iterator[v, r, r] \ r =iterator(rc, m) |> Iterator.map(snd)////// Returns the result of running all the actions in the map `m`.///pubdefsequence(m: Map[k, m[v]]): m[Map[k, v]] withApplicative[m] =let Map(t) = m;Functor.map(Map, Traversable.sequence(t))////// Returns the result of applying the applicative mapping function `f` to all the values of the/// map `m`.///pubdeftraverse(f: v1 -> m[v2] \ ef, m: Map[k, v1]): m[Map[k, v2]] \ efwithApplicative[m] =let Map(t) = m;Functor.map(Map, Traversable.traverse(f, t))////// Returns the result of applying the applicative mapping function `f` to all the key-value pairs/// of the map `m`.///pubdeftraverseWithKey(f: (k, v1) -> m[v2] \ ef, m: Map[k, v1]): m[Map[k, v2]] \ efwithApplicative[m] =let Map(t) = m;Functor.map(Map, RedBlackTree.mapAWithKey(f, t))////// Returns the concatenation of the string representation of each key `k`/// in `m` with `sep` inserted between each element.///pubdefjoinKeys(sep: String, m: Map[k, v]): StringwithToString[k] =let Map(t) = m;RedBlackTree.joinKeys(sep, t)////// Returns the concatenation of the string representation of each value `v`/// in `m` with `sep` inserted between each element.///pubdefjoinValues(sep: String, m: Map[k, v]): StringwithToString[v] =let Map(t) = m;RedBlackTree.joinValues(sep, t)////// Returns the concatenation of the string representation of each key-value pair/// `k => v` in `m` according to `f` with `sep` inserted between each element.///pubdefjoinWith(f: (k, v) -> String \ ef, sep: String, m: Map[k, v]): String \ ef =let Map(t) = m;RedBlackTree.joinWith(f, sep, t)}