@@ -35,6 +35,8 @@ module Data.IntMap.Strict.Refined
3535 , fromSet
3636 , Common.fromIntMap
3737 , Common.verifyIntMap
38+ , fromTraversable
39+ , fromTraversableWith
3840 , fromTraversableWithKey
3941 , FromTraversableProof(..)
4042 -- * Insertion
@@ -146,17 +148,52 @@ singleton k v = SomeIntMapWith (IntMap $ IntMap.singleton k v)
146148fromSet :: forall s a. KnownIntSet s => (Key s -> a) -> IntMap s a
147149fromSet f = IntMap $ IntMap.fromSet (f . unsafeKey) (reflect $ Proxy @s)
148150
149−-- | Create a map from an arbitrary traversable of key-value pairs.
151+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
152+-- repeated, the retained value is the last one in traversal order. If you're
153+-- looking for @fromList@, this is the function you want.
154+fromTraversable
155+ :: forall t a. Traversable t
156+ => t (Int, a) -> SomeIntMapWith (FromTraversableProof 'Int t Int) a
157+fromTraversable xs = SomeIntMapWith (IntMap m) $ FromTraversableProof proof
158+ where
159+ (m, proof) = mapAccumL
160+ (\s (k, v) -> let !s' = IntMap.insert k v s in (s', unsafeKey k))
161+ IntMap.empty
162+ xs
163+
164+-- | Create a map from an arbitrary traversable of key-value pairs, with a
165+-- function for combining values for repeated keys. The function is called as if
166+-- by 'foldl1', but flipped:
167+--
168+-- @
169+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
170+-- = 'singleton' k (f x3 (f x2 x1))
171+-- @
172+fromTraversableWith
173+ :: forall t a. Traversable t
174+ => (a -> a -> a)
175+ -> t (Int, a)
176+ -> SomeIntMapWith (FromTraversableProof 'Int t Int) a
177+fromTraversableWith f xs
178+ = SomeIntMapWith (IntMap m) $ FromTraversableProof proof
179+ where
180+ (m, proof) = mapAccumL
181+ (\s (k, v) -> let !s' = IntMap.insertWith f k v s in (s', unsafeKey k))
182+ IntMap.empty
183+ xs
184+
185+-- | Create a map from an arbitrary traversable of key-value pairs. Like
186+-- 'fromTraversableWith', but the combining function has access to the key.
150187fromTraversableWithKey
151188 :: forall t a. Traversable t
152189 => (Int -> a -> a -> a)
153190 -> t (Int, a)
154191 -> SomeIntMapWith (FromTraversableProof 'Int t Int) a
155−fromTraversableWithKey f xs = SomeIntMapWith (IntMap m)
156− $ FromTraversableProof proof
192+fromTraversableWithKey f xs
193+ = SomeIntMapWith (IntMap m) $ FromTraversableProof proof
157194 where
158195 (m, proof) = mapAccumL
159− (\s (k, v) -> (IntMap.insertWithKey f k v s, unsafeKey k))
196+ (\s (k, v) -> let !s' = IntMap.insertWithKey f k v s in (s', unsafeKey k))
160197 IntMap.empty
161198 xs
162199