std.map
Maps of keys to values, whichever they are: a theory of what std.ordmap, std.hashmap and std.hashtable each do, so that a definition written once works on any of them, and a program picks one by its type.
import std.hashmap as HashMapimport std.map as Map
-- | how many times each word appears, in a map of any kindcounts : {c : Type} -> {{m : Map.Mapping c @ { Key = String, Value = Int }}} -> List String -> ccounts ws = List.foldl (\t w -> m.insert t w (1 + fromMaybe 0 (m.lookup t w))) m.empty wsWhich one to pick:
- std.hashmap, a trie by the keys’ hashes: stable — its order is the hashes’, of what it binds alone — and a change to a map held elsewhere too (an old version kept) copies one path of it.
- std.hashtable, flat arrays: unstable — its order is of how it came to be — and a change to a table held elsewhere too copies all of it; but where one owner fills and reads it, the fastest.
- std.ordmap, a balanced tree by the keys’
Order: in the keys’ order.
Import this module for the instances too: an instance is in scope only in a module that imports its own.
Mapping
theory Mapping c where Key : Type Value : Type empty : c insert : c -> Key -> Value -> c lookup : c -> Key -> Maybe Value remove : c -> Key -> (Maybe Value, c) size : c -> Int foldl : {b : Type} -> (b -> Key -> Value -> b) -> b -> c -> bA map c of keys (Key) to values (Value): the map of none, a
key bound, looked up and removed (and what it was bound to, if it
was), how many keys are bound, and each key and its value folded,
in the map’s order.
empty
empty : {c : Type} -> {{m : Mapping c}} -> cThe map of no keys, of the kind c.
insert
insert : {c : Type} -> {{m : Mapping c}} -> c -> m.Key -> m.Value -> cThe map with key bound to value.
lookup
lookup : {c : Type} -> {{m : Mapping c}} -> c -> m.Key -> Maybe m.ValueWhat key is bound to, if it is.
remove
remove : {c : Type} -> {{m : Mapping c}} -> c -> m.Key -> (Maybe m.Value, c)What key was bound to, if it was, and the map without it.
size
size : {c : Type} -> {{m : Mapping c}} -> c -> IntHow many keys are bound.
foldl
foldl : {c b : Type} -> {{m : Mapping c}} -> (b -> m.Key -> m.Value -> b) -> b -> c -> bEach key and its value, from z, in the map’s order.
instanceMappingHashMap
instance instanceMappingHashMap : {k v : Type} -> {{hashing : HashMap.Hash k}} -> {{equality : Equality k}} -> Mapping (HashMap.HashMap k v)A hash map (std.hashmap): stable, its order the keys’ hashes’.
instanceMappingHashTable
instance instanceMappingHashTable : {k v : Type} -> {{hashing : HashMap.Hash k}} -> {{equality : Equality k}} -> Mapping (HashTable.HashTable k v)A hash table (std.hashtable): unstable, its order of how it came to be.
instanceMappingOrdMap
instance instanceMappingOrdMap : {k v : Type} -> {{ord : Order k}} -> Mapping (OrdMap.OrdMap k v)A map ordered by its keys (std.ordmap): in the keys’ order.
tally
tally : {c : Type} -> {{m : Mapping c @ { Value = Int }}} -> List m.Key -> cHow many times each key is in ks, in a map of any kind.
>>> HashMap.lookup (tally ["a", "b", "a"] : HashMap.HashMap String Int) "a"Just 2>>> HashTable.lookup (tally ["a", "b", "a"] : HashTable.HashTable String Int) "b"Just 1>>> OrdMap.toList (tally ["b", "a", "b"] : OrdMap.OrdMap String Int)Cons (MkPair "a" 1) (Cons (MkPair "b" 2) Nil)