@@ -8,6 +8,30 @@ module Dict (empty,singleton,insert
88 ,toList,fromList
99 ) where
1010
11+{-|A dictionary mapping unique keys to values. The keys can be any comparable
12+type. This includes `Int`, `Float`, `Time`, `Char`, `String`, and tuples or
13+lists of comparable types.
14+
15+Insert, remove, and query operations all take *O(log n)* time.
16+
17+# Build
18+@docs empty, singleton, insert, remove
19+
20+# Query
21+@docs member, lookup, findWithDefault
22+
23+# Combine
24+@docs union, intersect, diff
25+
26+# Lists
27+@docs keys, values, toList, fromList
28+
29+# Transform
30+@docs map, foldl, foldr
31+
32+-}
33+
34+
1135import open Basics
1236import open Maybe
1337import Native.Error
@@ -18,7 +42,7 @@ data NColor = Red | Black
1842
1943data Dict k v = RBNode NColor k v (Dict k v) (Dict k v) | RBEmpty
2044
21−-- Create an empty dictionary.
45+{-| Create an empty dictionary. -}
2246empty : Dict comparable v
2347empty = RBEmpty
2448
@@ -116,7 +140,7 @@ max t =
116140 }
117141--}
118142
119−-- Lookup the value associated with a key.
143+{-| Lookup the value associated with a key. -}
120144lookup : comparable -> Dict comparable v -> Maybe v
121145lookup k t =
122146 case t of
@@ -127,8 +151,8 @@ lookup k t =
127151 EQ -> Just v
128152 GT -> lookup k r
129153
130−-- Find the value associated with a key. If the key is not found,
131−-- return the default value.
154+{-| Find the value associated with a key. If the key is not found,
155+return the default value. -}
132156findWithDefault : v -> comparable -> Dict comparable v -> v
133157findWithDefault base k t =
134158 case t of
@@ -152,7 +176,7 @@ find k t =
152176 }
153177--}
154178
155−-- Determine if a key is in a dictionary.
179+{-| Determine if a key is in a dictionary. -}
156180member : comparable -> Dict comparable v -> Bool
157181-- Does t contain k?
158182member k t = isJust <| lookup k t
@@ -208,8 +232,8 @@ ensureBlackRoot t =
208232 RBNode Red k v l r -> RBNode Black k v l r
209233 _ -> t
210234
211−-- Insert a key-value pair into a dictionary. Replaces value when there is
212−-- a collision.
235+{-| Insert a key-value pair into a dictionary. Replaces value when there is
236+a collision. -}
213237insert : comparable -> v -> Dict comparable v -> Dict comparable v
214238insert k v t = -- Invariant: t is a valid left-leaning rb tree
215239 let ins t =
@@ -231,7 +255,7 @@ insert k v t = -- Invariant: t is a valid left-leaning rb tree
231255 else new_t)
232256--}
233257
234−-- Create a dictionary with one key-value pair.
258+{-| Create a dictionary with one key-value pair. -}
235259singleton : comparable -> v -> Dict comparable v
236260singleton k v = insert k v RBEmpty
237261
@@ -312,8 +336,8 @@ deleteMax t =
312336 in ensureBlackRoot (del t)
313337--}
314338
315−-- Remove a key-value pair from a dictionary. If the key is not found,
316−-- no changes are made.
339+{-| Remove a key-value pair from a dictionary. If the key is not found,
340+no changes are made. -}
317341remove : comparable -> Dict comparable v -> Dict comparable v
318342remove k t =
319343 let eq_and_noRightNode t =
@@ -346,58 +370,58 @@ remove k t =
346370 Native.Error.raise "invariants broken after remove")
347371--}
348372
349−-- Apply a function to all values in a dictionary.
373+{-| Apply a function to all values in a dictionary. -}
350374map : (a -> b) -> Dict comparable a -> Dict comparable b
351375map f t =
352376 case t of
353377 RBEmpty -> RBEmpty
354378 RBNode c k v l r -> RBNode c k (f v) (map f l) (map f r)
355379
356−-- Fold over the key-value pairs in a dictionary, in order from lowest
357−-- key to highest key.
380+{-| Fold over the key-value pairs in a dictionary, in order from lowest
381+key to highest key. -}
358382foldl : (comparable -> v -> b -> b) -> b -> Dict comparable v -> b
359383foldl f acc t =
360384 case t of
361385 RBEmpty -> acc
362386 RBNode _ k v l r -> foldl f (f k v (foldl f acc l)) r
363387
364−-- Fold over the key-value pairs in a dictionary, in order from highest
365−-- key to lowest key.
388+{-| Fold over the key-value pairs in a dictionary, in order from highest
389+key to lowest key. -}
366390foldr : (comparable -> v -> b -> b) -> b -> Dict comparable v -> b
367391foldr f acc t =
368392 case t of
369393 RBEmpty -> acc
370394 RBNode _ k v l r -> foldr f (f k v (foldr f acc r)) l
371395
372−-- Combine two dictionaries. If there is a collision, preference is given
373−-- to the first dictionary.
396+{-| Combine two dictionaries. If there is a collision, preference is given
397+to the first dictionary. -}
374398union : Dict comparable v -> Dict comparable v -> Dict comparable v
375399union t1 t2 = foldl insert t2 t1
376400
377−-- Keep a key-value pair when its key appears in the second dictionary.
378−-- Preference is given to values in the first dictionary.
401+{-| Keep a key-value pair when its key appears in the second dictionary.
402+Preference is given to values in the first dictionary. -}
379403intersect : Dict comparable v -> Dict comparable v -> Dict comparable v
380404intersect t1 t2 =
381405 let combine k v t = if k `member` t2 then insert k v t else t
382406 in foldl combine empty t1
383407
384−-- Keep a key-value pair when its key does not appear in the second dictionary.
385−-- Preference is given to the first dictionary.
408+{-| Keep a key-value pair when its key does not appear in the second dictionary.
409+Preference is given to the first dictionary. -}
386410diff : Dict comparable v -> Dict comparable v -> Dict comparable v
387411diff t1 t2 = foldl (\k v t -> remove k t) t1 t2
388412
389−-- Get all of the keys in a dictionary.
413+{-| Get all of the keys in a dictionary. -}
390414keys : Dict comparable v -> [comparable]
391415keys t = foldr (\k v acc -> k :: acc) [] t
392416
393−-- Get all of the values in a dictionary.
417+{-| Get all of the values in a dictionary. -}
394418values : Dict comparable v -> [v]
395419values t = foldr (\k v acc -> v :: acc) [] t
396420
397−-- Convert a dictionary into an association list of key-value pairs.
421+{-| Convert a dictionary into an association list of key-value pairs. -}
398422toList : Dict comparable v -> [(comparable,v)]
399423toList t = foldr (\k v acc -> (k,v) :: acc) [] t
400424
401−-- Convert an association list into a dictionary.
425+{-| Convert an association list into a dictionary. -}
402426fromList : [(comparable,v)] -> Dict comparable v
403427fromList assocs = List.foldl (\(k,v) d -> insert k v d) empty assocs