module Data.Map;
import ContainersPrelude open;
import Data.Set as Set;
open Set using {Set};
import Data.Set.AVL as AVL;
open AVL using {AVLTree};
import Data.BinaryTree as Tree;
import Data.Tmp open;
type Binding A B := binding A B;
key {A B} : Binding A B -> A
| (binding a _) := a;
value {A B} : Binding A B -> B
| (binding _ b) := b;
toPair {A B} : Binding A B -> A × B
| (binding a b) := a, b;
instance
bindingKeyOrdering {A B} {{Ord A}} : Ord (Binding A B) :=
mkOrd λ {b1 b2 := Ord.cmp (key b1) (key b2)};
type Map A B := mkMap (AVLTree (Binding A B));
empty {A B} : Map A B := mkMap AVL.empty;
insertWith {A B} {{Ord A}} (f : B -> B -> B) (k : A) (v : B)
: Map A B -> Map A B
| (mkMap s) :=
let
f' : Binding A B -> Binding A B -> Binding A B
| (binding a b1) (binding _ b2) := binding a (f b1 b2);
in mkMap (Set.insertWith f' (binding k v) s);
insert {A B : Type} {{Ord A}} : A -> B -> Map A B -> Map A B :=
insertWith λ {old new := new};
lookup {A B} {{Ord A}} (k : A) : Map A B -> Maybe B
| (mkMap s) := mapMaybe value (Set.lookupWith key k s);
fromListWith {A B} {{Ord A}} (f : B -> B -> B) (xs : List (A × B)) : Map A B :=
for (acc := empty) (k, v in xs)
insertWith f k v acc;
fromList {A B} {{Ord A}} : List (A × B) -> Map A B :=
fromListWith λ {old new := new};
toList {A B} : Map A B -> List (A × B)
| (mkMap s) := map (x in Set.toList s) toPair x;
size {A B} : Map A B -> Nat
| (mkMap s) := Set.size s;
instance
eqMapI {A B} {{Eq A}} {{Eq B}} : Eq (Map A B) := mkEq (Eq.eq on toList);
Last modified on 2023-12-07 10:36 UTC