@@ -1,6 +1,8 @@
11module Dict (empty,singleton,insert,update
22 ,lookup,findWithDefault
33 ,remove,member
4+ ,filter
5+ ,partition
46 ,foldl,foldr,map
57 ,union,intersect,diff
68 ,keys,values
@@ -26,7 +28,7 @@ Insert, remove, and query operations all take *O(log n)* time.
2628@docs keys, values, toList, fromList
2729
2830# Transform
29−@docs map, foldl, foldr
31+@docs map, foldl, foldr, filter, partition
3032
3133-}
3234
@@ -327,9 +329,7 @@ union t1 t2 = foldl insert t2 t1
327329{-| Keep a key-value pair when its key appears in the second dictionary.
328330Preference is given to values in the first dictionary. -}
329331intersect : Dict comparable v -> Dict comparable v -> Dict comparable v
330−intersect t1 t2 =
331− let combine k v t = if k `member` t2 then insert k v t else t
332− in foldl combine empty t1
332+intersect t1 t2 = filter (\k _ -> k `member` t2) t1
333333
334334{-| Keep a key-value pair when its key does not appear in the second dictionary.
335335Preference is given to the first dictionary. -}
@@ -351,3 +351,22 @@ toList t = foldr (\k v acc -> (k,v) :: acc) [] t
351351{-| Convert an association list into a dictionary. -}
352352fromList : [(comparable,v)] -> Dict comparable v
353353fromList assocs = List.foldl (\(k,v) d -> insert k v d) empty assocs
354+
355+{-| Keep a key-value pair when it satisfies a predicate. -}
356+filter : (comparable -> v -> Bool)
357+ -> Dict comparable v
358+ -> Dict comparable v
359+filter p =
360+ let add k v t = if p k v then insert k v t else t
361+ in foldl add empty
362+
363+{-| Partition the Dict according to a predicate. The first Dict contains all
364+key-value pairs which satisfy it; the second contains the rest. -}
365+partition : (comparable -> v -> Bool)
366+ -> Dict comparable v
367+ -> (Dict comparable v, Dict comparable v)
368+partition p =
369+ let add k v (t1, t2) = if p k v
370+ then (insert k v t1, t2)
371+ else (t1, insert k v t2)
372+ in foldl add (empty, empty)