@@ -11,14 +11,15 @@ module Dict (empty,singleton,insert
11import Maybe as Maybe
11import Maybe as Maybe
12import Native.Error as Error
12import Native.Error as Error
13import List as List
13import List as List
14+import Native.Utils (compare)
15data NColor = Red | Black
16data NColor = Red | Black
17−data Dict k v = Node NColor k v (Dict k v) (Dict k v) | Empty
18+data Dict k v = RBNode NColor k v (Dict k v) (Dict k v) | RBEmpty
19-- Create an empty dictionary.
20-- Create an empty dictionary.
20−empty : Dict k v
21+empty : Dict (Comparable k) v
21−empty = Empty
22+empty = RBEmpty
23{-- Helpers for checking invariants
24{-- Helpers for checking invariants
@@ -26,33 +27,32 @@ empty = Empty
26equal_pathLen t =
27equal_pathLen t =
27 let path_numBlacks t =
28 let path_numBlacks t =
29− { Empty -> 1
30+ RBEmpty -> 1
30− ; Node col _ _ l r ->
31+ RBNode col _ _ l r ->
31 let { bl = path_numBlacks l ; br = path_numBlacks r } in
32 let { bl = path_numBlacks l ; br = path_numBlacks r } in
32 if bl /= br || bl == 0-1 || br == 0-1
33 if bl /= br || bl == 0-1 || br == 0-1
34 else bl + (if col == Red then 0 else 1)
35 else bl + (if col == Red then 0 else 1)
36 in 0-1 /= path_numBlacks t
36 in 0-1 /= path_numBlacks t
38rootBlack t =
38rootBlack t =
40− { Empty -> True
40+ RBEmpty -> True
41− ; Node Black _ _ _ _ -> True
41+ RBNode Black _ _ _ _ -> True
42− ; _ -> False }
42+ _ -> False
44redBlack_children t =
44redBlack_children t =
45 case t of
45 case t of
46− { Node Red _ _ (Node Red _ _ _ _) _ -> False
46+ { RBNode Red _ _ (RBNode Red _ _ _ _) _ -> False
47− ; Node Red _ _ _ (Node Red _ _ _ _) -> False
47+ ; RBNode Red _ _ _ (RBNode Red _ _ _ _) -> False
48− ; Empty -> True
48+ ; RBEmpty -> True
49− ; Node _ _ _ l r -> redBlack_children l && redBlack_children r
49+ ; RBNode _ _ _ l r -> redBlack_children l && redBlack_children r
52findExtreme f t =
52findExtreme f t =
54− { Empty -> Nothing
54+ { RBEmpty -> Nothing
55− ; Node c k _ l r ->
55+ ; RBNode c k _ l r ->
56 case findExtreme f (f (l,r)) of
56 case findExtreme f (f (l,r)) of
57 { Nothing -> Just k
57 { Nothing -> Just k
58 ; Just k' -> Just k' }
58 ; Just k' -> Just k' }
@@ -76,8 +76,8 @@ olte xo yo = optionRelation (<=) True xo yo
77ordered t =
77ordered t =
79− { Empty -> True
79+ { RBEmpty -> True
80− ; Node c k v l r ->
80+ ; RBNode c k v l r ->
81 let (lmax,rmin) = (findmaxRbt l, findminRbt r) in
81 let (lmax,rmin) = (findmaxRbt l, findminRbt r) in
82 olte lmax (Just k) && olte (Just k) rmin && ordered l && ordered r
82 olte lmax (Just k) && olte (Just k) rmin && ordered l && ordered r
@@ -85,10 +85,10 @@ ordered t =
85-- Check that there aren't any right red nodes in the tree *)
85-- Check that there aren't any right red nodes in the tree *)
86leftLeaning t =
86leftLeaning t =
88− { Empty -> True
88+ { RBEmpty -> True
89− ; Node _ _ _ (Node Black _ _ _ _) (Node Red _ _ _ _) -> False
89+ ; RBNode _ _ _ (RBNode Black _ _ _ _) (RBNode Red _ _ _ _) -> False
90− ; Node _ _ _ Empty (Node Red _ _ _ _) -> False
90+ ; RBNode _ _ _ RBEmpty (RBNode Red _ _ _ _) -> False
91− ; Node _ _ _ l r -> (leftLeaning l) && (leftLeaning r)
91+ ; RBNode _ _ _ l r -> (leftLeaning l) && (leftLeaning r)
94invariants_hold t =
94invariants_hold t =
@@ -102,36 +102,37 @@ invariants_hold t =
102min : Dict k v -> (k,v)
102min : Dict k v -> (k,v)
104 case t of
104 case t of
105− Node _ k v Empty _ -> (k,v)
105+ RBNode _ k v RBEmpty _ -> (k,v)
106− Node _ _ _ l _ -> min l
106+ RBNode _ _ _ l _ -> min l
107− Empty -> Error.raise "(min Empty) is not defined"
107+ RBEmpty -> Error.raise "(min Empty) is not defined"
111 case t of
111 case t of
112− { Node _ k v _ Empty -> (k,v)
112+ { RBNode _ k v _ RBEmpty -> (k,v)
113− ; Node _ _ _ _ r -> max r
113+ ; RBNode _ _ _ _ r -> max r
114− ; Empty -> Error.raise "(max Empty) is not defined"
114+ ; RBEmpty -> Error.raise "(max Empty) is not defined"
118-- Lookup the value associated with a key.
118-- Lookup the value associated with a key.
119−lookup : k -> Dict k v -> Maybe v
119+lookup : Comparable k -> Dict (Comparable k) v -> Maybe v
120lookup k t =
120lookup k t =
121 case t of
121 case t of
122− Empty -> Nothing
122+ RBEmpty -> Nothing
123− Node _ k' v l r ->
123+ RBNode _ k' v l r ->
124 case compare k k' of
124 case compare k k' of
125 LT -> lookup k l
125 LT -> lookup k l
126 EQ -> Just v
126 EQ -> Just v
127 GT -> lookup k r
127 GT -> lookup k r
129−-- Find the value associated with a key. If the key is not found, return the default value.
129+-- Find the value associated with a key. If the key is not found,
130+-- return the default value.
130−findWithDefault : v -> k -> Dict k v -> v
131+findWithDefault : v -> Comparable k -> Dict (Comparable k) v -> v
131findWithDefault base k t =
132findWithDefault base k t =
132 case t of
133 case t of
133− Empty -> base
134+ RBEmpty -> base
134− Node _ k' v l r ->
135+ RBNode _ k' v l r ->
135 case compare k k' of
136 case compare k k' of
136 LT -> findWithDefault base k l
137 LT -> findWithDefault base k l
@@ -141,8 +142,8 @@ findWithDefault base k t =
141-- Find the value associated with a key. If the key is not found, there will be a runtime error.
142-- Find the value associated with a key. If the key is not found, there will be a runtime error.
142find k t =
143find k t =
143 case t of
144 case t of
144− { Empty -> Error.raise "Key was not found in dictionary!"
145+ { RBEmpty -> Error.raise "Key was not found in dictionary!"
145− ; Node _ k' v l r ->
146+ ; RBNode _ k' v l r ->
146 case compare k k' of
147 case compare k k' of
147 { LT -> find k l
148 { LT -> find k l
148 ; EQ -> v
149 ; EQ -> v
@@ -151,14 +152,14 @@ find k t =
153-- Determine if a key is in a dictionary.
154-- Determine if a key is in a dictionary.
154−member : k -> Dict k v -> Bool
155+member : Comparable k -> Dict (Comparable k) v -> Bool
155-- Does t contain k?
156-- Does t contain k?
156member k t = Maybe.isJust $ lookup k t
157member k t = Maybe.isJust $ lookup k t
158rotateLeft : Dict k v -> Dict k v
159rotateLeft : Dict k v -> Dict k v
159rotateLeft t =
160rotateLeft t =
160 case t of
161 case t of
161− Node cy ky vy a (Node cz kz vz b c) -> Node cy kz vz (Node Red ky vy a b) c
162+ RBNode cy ky vy a (RBNode cz kz vz b c) -> RBNode cy kz vz (RBNode Red ky vy a b) c
162 _ -> Error.raise "rotateLeft of a node without enough children"
163 _ -> Error.raise "rotateLeft of a node without enough children"
164-- rotateRight -- the reverse, and
165-- rotateRight -- the reverse, and
@@ -166,19 +167,19 @@ rotateLeft t =
166rotateRight : Dict k v -> Dict k v
167rotateRight : Dict k v -> Dict k v
167rotateRight t =
168rotateRight t =
168 case t of
169 case t of
169− Node cz kz vz (Node cy ky vy a b) c -> Node cz ky vy a (Node Red kz vz b c)
170+ RBNode cz kz vz (RBNode cy ky vy a b) c -> RBNode cz ky vy a (RBNode Red kz vz b c)
170 _ -> Error.raise "rotateRight of a node without enough children"
171 _ -> Error.raise "rotateRight of a node without enough children"
172rotateLeftIfNeeded : Dict k v -> Dict k v
173rotateLeftIfNeeded : Dict k v -> Dict k v
173rotateLeftIfNeeded t =
174rotateLeftIfNeeded t =
174 case t of
175 case t of
175− Node _ _ _ _ (Node Red _ _ _ _) -> rotateLeft t
176+ RBNode _ _ _ _ (RBNode Red _ _ _ _) -> rotateLeft t
178rotateRightIfNeeded : Dict k v -> Dict k v
179rotateRightIfNeeded : Dict k v -> Dict k v
179rotateRightIfNeeded t =
180rotateRightIfNeeded t =
180 case t of
181 case t of
181− Node _ _ _ (Node Red _ _ (Node Red _ _ _ _) _) _ -> rotateRight t
182+ RBNode _ _ _ (RBNode Red _ _ (RBNode Red _ _ _ _) _) _ -> rotateRight t
184otherColor c = case c of { Red -> Black ; Black -> Red }
185otherColor c = case c of { Red -> Black ; Black -> Red }
@@ -186,16 +187,16 @@ otherColor c = case c of { Red -> Black ; Black -> Red }
186color_flip : Dict k v -> Dict k v
187color_flip : Dict k v -> Dict k v
187color_flip t =
188color_flip t =
188 case t of
189 case t of
189− Node c1 bk bv (Node c2 ak av la ra) (Node c3 ck cv lc rc) ->
190+ RBNode c1 bk bv (RBNode c2 ak av la ra) (RBNode c3 ck cv lc rc) ->
190− Node (otherColor c1) bk bv
191+ RBNode (otherColor c1) bk bv
191− (Node (otherColor c2) ak av la ra)
192+ (RBNode (otherColor c2) ak av la ra)
192− (Node (otherColor c3) ck cv lc rc)
193+ (RBNode (otherColor c3) ck cv lc rc)
193 _ -> Error.raise "color_flip called on a Empty or Node with a Empty child"
194 _ -> Error.raise "color_flip called on a Empty or Node with a Empty child"
195color_flipIfNeeded : Dict k v -> Dict k v
196color_flipIfNeeded : Dict k v -> Dict k v
196color_flipIfNeeded t =
197color_flipIfNeeded t =
197 case t of
198 case t of
198− Node _ _ _ (Node Red _ _ _ _) (Node Red _ _ _ _) -> color_flip t
199+ RBNode _ _ _ (RBNode Red _ _ _ _) (RBNode Red _ _ _ _) -> color_flip t
201fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
202fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
@@ -203,21 +204,21 @@ fixUp t = color_flipIfNeeded (rotateRightIfNeeded (rotateLeftIfNeeded t))
203ensureBlackRoot : Dict k v -> Dict k v
204ensureBlackRoot : Dict k v -> Dict k v
204ensureBlackRoot t =
205ensureBlackRoot t =
205 case t of
206 case t of
206− Node Red k v l r -> Node Black k v l r
207+ RBNode Red k v l r -> RBNode Black k v l r
209−-- Insert a key-value pair into a dictionary. Replaces value when there is a collision.
210+-- Insert a key-value pair into a dictionary. Replaces value when there is
212+insert : Comparable k -> v -> Dict (Comparable k) v -> Dict (Comparable k) v
210−-- Invariant: t is a valid left-leaning rb tree *)
213+insert k v t = -- Invariant: t is a valid left-leaning rb tree
211−insert : k -> v -> Dict k v -> Dict k v
213 let ins t =
214 let ins t =
214 case t of
215 case t of
215− Empty -> Node Red k v Empty Empty
216+ RBEmpty -> RBNode Red k v RBEmpty RBEmpty
216− Node c k' v' l r ->
217+ RBNode c k' v' l r ->
217 let h = case compare k k' of
218 let h = case compare k k' of
218− LT -> Node c k' v' (ins l) r
219+ LT -> RBNode c k' v' (ins l) r
219− EQ -> Node c k' v l r -- replace
220+ EQ -> RBNode c k' v l r -- replace
220− GT -> Node c k' v' l (ins r)
221+ GT -> RBNode c k' v' l (ins r)
221 in fixUp h
222 in fixUp h
222 in ensureBlackRoot (ins t)
223 in ensureBlackRoot (ins t)
@@ -230,47 +231,47 @@ insert k v t =
232-- Create a dictionary with one key-value pair.
233-- Create a dictionary with one key-value pair.
233−singleton : k -> v -> Dict k v
234+singleton : Comparable k -> v -> Dict (Comparable k) v
234−singleton k v = insert k v Empty
235+singleton k v = insert k v RBEmpty
236isRed : Dict k v -> Bool
237isRed : Dict k v -> Bool
238 case t of
239 case t of
239− Node Red _ _ _ _ -> True
240+ RBNode Red _ _ _ _ -> True
240 _ -> False
241 _ -> False
242isRedLeft : Dict k v -> Bool
243isRedLeft : Dict k v -> Bool
243isRedLeft t =
244isRedLeft t =
244 case t of
245 case t of
245− Node _ _ _ (Node Red _ _ _ _) _ -> True
246+ RBNode _ _ _ (RBNode Red _ _ _ _) _ -> True
246 _ -> False
247 _ -> False
248isRedLeftLeft : Dict k v -> Bool
249isRedLeftLeft : Dict k v -> Bool
249isRedLeftLeft t =
250isRedLeftLeft t =
250 case t of
251 case t of
251− Node _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) _ -> True
252+ RBNode _ _ _ (RBNode _ _ _ (RBNode Red _ _ _ _) _) _ -> True
252 _ -> False
253 _ -> False
254isRedRight : Dict k v -> Bool
255isRedRight : Dict k v -> Bool
255isRedRight t =
256isRedRight t =
256 case t of
257 case t of
257− Node _ _ _ _ (Node Red _ _ _ _) -> True
258+ RBNode _ _ _ _ (RBNode Red _ _ _ _) -> True
258 _ -> False
259 _ -> False
260isRedRightLeft : Dict k v -> Bool
261isRedRightLeft : Dict k v -> Bool
261isRedRightLeft t =
262isRedRightLeft t =
262 case t of
263 case t of
263− Node _ _ _ _ (Node _ _ _ (Node Red _ _ _ _) _) -> True
264+ RBNode _ _ _ _ (RBNode _ _ _ (RBNode Red _ _ _ _) _) -> True
264 _ -> False
265 _ -> False
266moveRedLeft : Dict k v -> Dict k v
267moveRedLeft : Dict k v -> Dict k v
267moveRedLeft t =
268moveRedLeft t =
268 let t' = color_flip t in
269 let t' = color_flip t in
269 case t' of
270 case t' of
270− Node c k v l r ->
271+ RBNode c k v l r ->
271 case r of
272 case r of
272− Node _ _ _ (Node Red _ _ _ _) _ ->
273+ RBNode _ _ _ (RBNode Red _ _ _ _) _ ->
273− color_flip (rotateLeft (Node c k v l (rotateRight r)))
274+ color_flip (rotateLeft (RBNode c k v l (rotateRight r)))
@@ -291,10 +292,10 @@ deleteMin : Dict k v -> Dict k v
291deleteMin t =
292deleteMin t =
292 let del t =
293 let del t =
293 case t of
294 case t of
294− Node _ _ _ Empty _ -> Empty
295+ RBNode _ _ _ RBEmpty _ -> RBEmpty
295 _ -> case moveRedLeftIfNeeded t of
296 _ -> case moveRedLeftIfNeeded t of
296− Node c k v l r -> fixUp (Node c k v (del l) r)
297+ RBNode c k v l r -> fixUp (RBNode c k v (del l) r)
297− Empty -> Empty
298+ RBEmpty -> RBEmpty
298 in ensureBlackRoot (del t)
299 in ensureBlackRoot (del t)
@@ -302,36 +303,37 @@ deleteMax t =
302 let del t =
303 let del t =
303 let t' = if isRedLeft t then rotateRight t else t in
304 let t' = if isRedLeft t then rotateRight t else t in
304 case t' of
305 case t' of
305− { Node _ _ _ _ Empty -> Empty
306+ { RBNode _ _ _ _ RBEmpty -> RBEmpty
306 ; _ -> let t'' = moveRedRightIfNeeded t' in
307 ; _ -> let t'' = moveRedRightIfNeeded t' in
307 case t'' of
308 case t'' of
308− { Node c k v l r -> fixUp (Node c k v l (del r))
309+ { RBNode c k v l r -> fixUp (RBNode c k v l (del r))
309− ; Empty -> Empty } }
310+ ; RBEmpty -> RBEmpty } }
310 in ensureBlackRoot (del t)
311 in ensureBlackRoot (del t)
313−-- Remove a key-value pair from a dictionary. If the key is not found, no changes are made.
314+-- Remove a key-value pair from a dictionary. If the key is not found,
315+-- no changes are made.
314−remove : k -> Dict k v -> Dict k v
316+remove : Comparable k -> Dict (Comparable k) v -> Dict (Comparable k) v
315remove k t =
317remove k t =
316 let eq_and_noRightNode t =
318 let eq_and_noRightNode t =
317− case t of { Node _ k' _ _ Empty -> k == k' ; _ -> False }
319+ case t of { RBNode _ k' _ _ RBEmpty -> k == k' ; _ -> False }
318− eq t = case t of { Node _ k' _ _ _ -> k == k' ; _ -> False }
320+ eq t = case t of { RBNode _ k' _ _ _ -> k == k' ; _ -> False }
319 delLT t = case moveRedLeftIfNeeded t of
321 delLT t = case moveRedLeftIfNeeded t of
320− Node c k' v l r -> fixUp (Node c k' v (del l) r)
322+ RBNode c k' v l r -> fixUp (RBNode c k' v (del l) r)
321− Empty -> Error.raise "delLT on Empty"
323+ RBEmpty -> Error.raise "delLT on Empty"
322 delEQ t = case t of -- Replace with successor
324 delEQ t = case t of -- Replace with successor
323− Node c _ _ l r -> let (k',v') = min r in
325+ RBNode c _ _ l r -> let (k',v') = min r in
324− fixUp (Node c k' v' l (deleteMin r))
326+ fixUp (RBNode c k' v' l (deleteMin r))
325− Empty -> Error.raise "delEQ called on a Empty"
327+ RBEmpty -> Error.raise "delEQ called on a Empty"
326 delGT t = case t of
328 delGT t = case t of
327− Node c k' v l r -> fixUp (Node c k' v l (del r))
329+ RBNode c k' v l r -> fixUp (RBNode c k' v l (del r))
328− Empty -> Error.raise "delGT called on a Empty"
330+ RBEmpty -> Error.raise "delGT called on a Empty"
329 del t = case t of
331 del t = case t of
330− Empty -> Empty
332+ RBEmpty -> RBEmpty
331− Node _ k' _ _ _ ->
333+ RBNode _ k' _ _ _ ->
332 if k < k' then delLT t else
334 if k < k' then delLT t else
333 let u = if isRedLeft t then rotateRight t else t in
335 let u = if isRedLeft t then rotateRight t else t in
334− if eq_and_noRightNode u then Empty else
336+ if eq_and_noRightNode u then RBEmpty else
335 let t' = moveRedRightIfNeeded t in
337 let t' = moveRedRightIfNeeded t in
336 if eq t' then delEQ t' else delGT t'
338 if eq t' then delEQ t' else delGT t'
337 in if member k t then ensureBlackRoot (del t) else t
339 in if member k t then ensureBlackRoot (del t) else t
@@ -344,52 +346,58 @@ remove k t =
346-- Apply a function to all values in a dictionary.
348-- Apply a function to all values in a dictionary.
347−map : (a -> b) -> Dict k a -> Dict k b
349+map : (a -> b) -> Dict (Comparable k) a -> Dict (Comparable k) b
349 case t of
351 case t of
350− Empty -> Empty
352+ RBEmpty -> RBEmpty
351− Node c k v l r -> Node c k (f v) (map f l) (map f r)
353+ RBNode c k v l r -> RBNode c k (f v) (map f l) (map f r)
353−-- Fold over the key-value pairs in a dictionary, in order from lowest key to highest key.
355+-- Fold over the key-value pairs in a dictionary, in order from lowest
356+-- key to highest key.
354−foldl : (k -> v -> b -> b) -> b -> Dict k v -> b
357+foldl : (Comparable k -> v -> b -> b) -> b -> Dict (Comparable k) v -> b
355foldl f acc t =
358foldl f acc t =
356 case t of
359 case t of
357− Empty -> acc
360+ RBEmpty -> acc
358− Node _ k v l r -> foldl f (f k v (foldl f acc l)) r
361+ RBNode _ k v l r -> foldl f (f k v (foldl f acc l)) r
360−-- Fold over the key-value pairs in a dictionary, in order from highest key to lowest key.
363+-- Fold over the key-value pairs in a dictionary, in order from highest
364+-- key to lowest key.
361−foldr : (k -> v -> b -> b) -> b -> Dict k v -> b
365+foldr : (Comparable k -> v -> b -> b) -> b -> Dict (Comparable k) v -> b
362foldr f acc t =
366foldr f acc t =
363 case t of
367 case t of
364− Empty -> acc
368+ RBEmpty -> acc
365− Node _ k v l r -> foldr f (f k v (foldr f acc r)) l
369+ RBNode _ k v l r -> foldr f (f k v (foldr f acc r)) l
367−-- Combine two dictionaries. If there is a collision, preference is given to the first dictionary.
371+-- Combine two dictionaries. If there is a collision, preference is given
372+-- to the first dictionary.
368−union : Dict k v -> Dict k v -> Dict k v
373+union : Dict (Comparable k) v -> Dict (Comparable k) v -> Dict (Comparable k) v
369union t1 t2 = foldl insert t2 t1
374union t1 t2 = foldl insert t2 t1
371−-- Keep a key-value pair when its key appears in the second dictionary. Preference is given to values in the first dictionary.
376+-- Keep a key-value pair when its key appears in the second dictionary.
377+-- Preference is given to values in the first dictionary.
372−intersect : Dict k v -> Dict k v -> Dict k v
378+intersect : Dict (Comparable k) v
379+ -> Dict (Comparable k) v -> Dict (Comparable k) v
373intersect t1 t2 =
380intersect t1 t2 =
374 let combine k v t = if k `member` t2 then insert k v t else t
381 let combine k v t = if k `member` t2 then insert k v t else t
375 in foldl combine empty t1
382 in foldl combine empty t1
377−-- Keep a key-value pair when its key does not appear in the second dictionary. Preference is given to the first dictionary.
384+-- Keep a key-value pair when its key does not appear in the second dictionary.
385+-- Preference is given to the first dictionary.
378−diff : Dict k v -> Dict k v -> Dict k v
386+diff : Dict (Comparable k) v -> Dict (Comparable k) v -> Dict (Comparable k) v
379diff t1 t2 = foldl (\k v t -> remove k t) t1 t2
387diff t1 t2 = foldl (\k v t -> remove k t) t1 t2
381-- Get all of the keys in a dictionary.
389-- Get all of the keys in a dictionary.
382−keys : Dict k v -> [k]
390+keys : Dict (Comparable k) v -> [Comparable k]
383keys t = foldr (\k v acc -> k :: acc) [] t
391keys t = foldr (\k v acc -> k :: acc) [] t
385-- Get all of the values in a dictionary.
393-- Get all of the values in a dictionary.
386−values : Dict k v -> [v]
394+values : Dict (Comparable k) v -> [v]
387values t = foldr (\k v acc -> v :: acc) [] t
395values t = foldr (\k v acc -> v :: acc) [] t
389-- Convert a dictionary into an association list of key-value pairs.
397-- Convert a dictionary into an association list of key-value pairs.
390−toList : Dict k v -> [(k,v)]
398+toList : Dict (Comparable k) v -> [(Comparable k,v)]
391toList t = foldr (\k v acc -> (k,v) :: acc) [] t
399toList t = foldr (\k v acc -> (k,v) :: acc) [] t
393-- Convert an association list into a dictionary.
401-- Convert an association list into a dictionary.
394−fromList : [(k,v)] -> Dict k v
402+fromList : [(Comparable k,v)] -> Dict (Comparable k) v
395−fromList assocs = List.foldl (uncurry insert) empty assocs
403+fromList assocs = List.foldl (\(k,v) d -> insert k v d) empty assocs