2019-05-14 00:36:04 +03:00
|
|
|
type Trie k v = { head : Optional v, tail : Map k (Trie k v) }
|
|
|
|
|
|
|
|
namespace Trie where
|
|
|
|
empty : Trie k v
|
|
|
|
empty = Trie None Map.empty
|
|
|
|
|
|
|
|
lookup : [k] -> Trie k v -> Optional v
|
2020-02-22 02:48:12 +03:00
|
|
|
lookup path t = match path with
|
2019-05-22 18:47:18 +03:00
|
|
|
[] -> Trie.head t
|
|
|
|
p +: ps -> flatMap (lookup ps) (Map.lookup p (Trie.tail t))
|
2019-05-14 00:36:04 +03:00
|
|
|
|
|
|
|
unionWith : (v -> v -> v) -> Trie k v -> Trie k v -> Trie k v
|
|
|
|
unionWith f t1 t2 =
|
2019-05-22 18:47:18 +03:00
|
|
|
h1 = Trie.head t1
|
|
|
|
h2 = Trie.head t2
|
2020-02-22 02:48:12 +03:00
|
|
|
Trie (map2 f h1 h2 `orElse` h1 `orElse` h2)
|
2019-05-22 18:47:18 +03:00
|
|
|
(Map.unionWith (unionWith f) (Trie.tail t1) (Trie.tail t2))
|
2019-05-14 20:43:21 +03:00
|
|
|
|
|
|
|
Trie.union : Trie k v -> Trie k v -> Trie k v
|
|
|
|
Trie.union = Trie.unionWith const
|
|
|
|
|
|
|
|
Trie.insert : [k] -> v -> Trie k v -> Trie k v
|
|
|
|
Trie.insert path v t =
|
2019-05-22 18:47:18 +03:00
|
|
|
Trie.unionWith const (Trie.singleton path v) t
|
2019-05-14 20:43:21 +03:00
|
|
|
|
|
|
|
Trie.singleton : [k] -> v -> Trie k v
|
2020-02-22 02:48:12 +03:00
|
|
|
Trie.singleton path v =
|
|
|
|
match path with
|
|
|
|
[] -> Trie (Some v) empty
|
2019-06-27 16:36:57 +03:00
|
|
|
k +: ks -> Trie None (Map.fromList [(k, Trie.singleton ks v)])
|
2019-05-23 17:24:44 +03:00
|
|
|
|
|
|
|
use Trie tail head
|
2019-05-22 18:47:18 +03:00
|
|
|
|
|
|
|
Trie.map : (v1 -> v2) -> Trie k v1 -> Trie k v2
|
|
|
|
Trie.map f t = Trie (map f (head t)) (map (Trie.map f) (tail t))
|
|
|
|
|
|
|
|
Trie.mapKeys : (k1 -> k2) -> Trie k1 v -> Trie k2 v
|
|
|
|
Trie.mapKeys f t =
|
|
|
|
Trie (head t) (Map.mapKeys f (Map.map (Trie.mapKeys f) (tail t)))
|