git.iko.soy/typeable/refined-containers
on main help sign in
Add fromTraversable and fromTraversableWith
commitf44eb7bcc6102f2fdc7b0ab1dbcce932066eaf7c authormniip <mniip@mniip.com> dateSun 2 Mar 2025, 13:53 (2 years ago) parent3b2cb79
6 files changed+231−11
src/Data/HashMap/Refined.hs+38−1 src/Data/HashMap/Strict/Refined.hs+40−3 src/Data/IntMap/Refined.hs+38−1 src/Data/IntMap/Strict/Refined.hs+41−4 src/Data/Map/Refined.hs+37−1 src/Data/Map/Strict/Refined.hs+37−1
src/Data/HashMap/Refined.hs+38−1
@@ -44,6 +44,8 @@ module Data.HashMap.Refined
4444 , fromSet
4545 , Common.fromHashMap
4646 , Common.verifyHashMap
47+ , fromTraversable
48+ , fromTraversableWith
4749 , fromTraversableWithKey
4850 , FromTraversableProof(..)
4951 -- * Insertion
@@ -137,7 +139,42 @@ singleton
137139singleton k v = SomeHashMapWith (HashMap $ HashMap.singleton k v)
138140 $ SingletonProof (unsafeKey k)
139141
140−-- | Create a map from an arbitrary traversable of key-value pairs.
142+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
143+-- repeated, the retained value is the last one in traversal order. If you're
144+-- looking for @fromList@, this is the function you want.
145+fromTraversable
146+ :: forall t k a. (Traversable t, Hashable k)
147+ => t (k, a) -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a
148+fromTraversable xs = SomeHashMapWith (HashMap m) $ FromTraversableProof proof
149+ where
150+ (m, proof) = mapAccumL
151+ (\s (k, v) -> let !s' = HashMap.insert k v s in (s', unsafeKey k))
152+ HashMap.empty
153+ xs
154+
155+-- | Create a map from an arbitrary traversable of key-value pairs, with a
156+-- function for combining values for repeated keys. The function is called as if
157+-- by 'foldl1', but flipped:
158+--
159+-- @
160+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
161+-- = 'singleton' k (f x3 (f x2 x1))
162+-- @
163+fromTraversableWith
164+ :: forall t k a. (Traversable t, Hashable k)
165+ => (a -> a -> a)
166+ -> t (k, a)
167+ -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a
168+fromTraversableWith f xs
169+ = SomeHashMapWith (HashMap m) $ FromTraversableProof proof
170+ where
171+ (m, proof) = mapAccumL
172+ (\s (k, v) -> let !s' = HashMap.insertWith f k v s in (s', unsafeKey k))
173+ HashMap.empty
174+ xs
175+
176+-- | Create a map from an arbitrary traversable of key-value pairs. Like
177+-- 'fromTraversableWith', but the combining function has access to the key.
141178fromTraversableWithKey
142179 :: forall t k a. (Traversable t, Hashable k)
143180 => (k -> a -> a -> a)
src/Data/HashMap/Strict/Refined.hs+40−3
@@ -44,6 +44,8 @@ module Data.HashMap.Strict.Refined
4444 , fromSet
4545 , Common.fromHashMap
4646 , Common.verifyHashMap
47+ , fromTraversable
48+ , fromTraversableWith
4749 , fromTraversableWithKey
4850 , FromTraversableProof(..)
4951 -- * Insertion
@@ -145,14 +147,49 @@ fromSet :: forall s k a. KnownHashSet s k => (Key s k -> a) -> HashMap s k a
145147fromSet f = HashMap $ HashMap.mapWithKey (\k _ -> f $ unsafeKey k)
146148 $ HashSet.toMap (reflect $ Proxy @s)
147149
148−-- | Create a map from an arbitrary traversable of key-value pairs.
150+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
151+-- repeated, the retained value is the last one in traversal order. If you're
152+-- looking for @fromList@, this is the function you want.
153+fromTraversable
154+ :: forall t k a. (Traversable t, Hashable k)
155+ => t (k, a) -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a
156+fromTraversable xs = SomeHashMapWith (HashMap m) $ FromTraversableProof proof
157+ where
158+ (m, proof) = mapAccumL
159+ (\s (k, v) -> let !s' = HashMap.insert k v s in (s', unsafeKey k))
160+ HashMap.empty
161+ xs
162+
163+-- | Create a map from an arbitrary traversable of key-value pairs, with a
164+-- function for combining values for repeated keys. The function is called as if
165+-- by 'foldl1', but flipped:
166+--
167+-- @
168+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
169+-- = 'singleton' k (f x3 (f x2 x1))
170+-- @
171+fromTraversableWith
172+ :: forall t k a. (Traversable t, Hashable k)
173+ => (a -> a -> a)
174+ -> t (k, a)
175+ -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a
176+fromTraversableWith f xs
177+ = SomeHashMapWith (HashMap m) $ FromTraversableProof proof
178+ where
179+ (m, proof) = mapAccumL
180+ (\s (k, v) -> let !s' = HashMap.insertWith f k v s in (s', unsafeKey k))
181+ HashMap.empty
182+ xs
183+
184+-- | Create a map from an arbitrary traversable of key-value pairs. Like
185+-- 'fromTraversableWith', but the combining function has access to the key.
149186fromTraversableWithKey
150187 :: forall t k a. (Traversable t, Hashable k)
151188 => (k -> a -> a -> a)
152189 -> t (k, a)
153190 -> SomeHashMapWith (FromTraversableProof 'Hashed t k) k a
154−fromTraversableWithKey f xs = SomeHashMapWith (HashMap m)
155− $ FromTraversableProof proof
191+fromTraversableWithKey f xs
192+ = SomeHashMapWith (HashMap m) $ FromTraversableProof proof
156193 where
157194 (m, proof) = mapAccumL
158195 (\s (k, v)
src/Data/IntMap/Refined.hs+38−1
@@ -35,6 +35,8 @@ module Data.IntMap.Refined
3535 , fromSet
3636 , Common.fromIntMap
3737 , Common.verifyIntMap
38+ , fromTraversable
39+ , fromTraversableWith
3840 , fromTraversableWithKey
3941 , FromTraversableProof(..)
4042 -- * Insertion
@@ -140,7 +142,42 @@ singleton :: forall a. Int -> a -> SomeIntMapWith (SingletonProof 'Int Int) a
140142singleton k v = SomeIntMapWith (IntMap $ IntMap.singleton k v)
141143 $ SingletonProof (unsafeKey k)
142144
143−-- | Create a map from an arbitrary traversable of key-value pairs.
145+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
146+-- repeated, the retained value is the last one in traversal order. If you're
147+-- looking for @fromList@, this is the function you want.
148+fromTraversable
149+ :: forall t a. Traversable t
150+ => t (Int, a) -> SomeIntMapWith (FromTraversableProof 'Int t Int) a
151+fromTraversable xs = SomeIntMapWith (IntMap m) $ FromTraversableProof proof
152+ where
153+ (m, proof) = mapAccumL
154+ (\s (k, v) -> let !s' = IntMap.insert k v s in (s', unsafeKey k))
155+ IntMap.empty
156+ xs
157+
158+-- | Create a map from an arbitrary traversable of key-value pairs, with a
159+-- function for combining values for repeated keys. The function is called as if
160+-- by 'foldl1', but flipped:
161+--
162+-- @
163+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
164+-- = 'singleton' k (f x3 (f x2 x1))
165+-- @
166+fromTraversableWith
167+ :: forall t a. Traversable t
168+ => (a -> a -> a)
169+ -> t (Int, a)
170+ -> SomeIntMapWith (FromTraversableProof 'Int t Int) a
171+fromTraversableWith f xs
172+ = SomeIntMapWith (IntMap m) $ FromTraversableProof proof
173+ where
174+ (m, proof) = mapAccumL
175+ (\s (k, v) -> let !s' = IntMap.insertWith f k v s in (s', unsafeKey k))
176+ IntMap.empty
177+ xs
178+
179+-- | Create a map from an arbitrary traversable of key-value pairs. Like
180+-- 'fromTraversableWith', but the combining function has access to the key.
144181fromTraversableWithKey
145182 :: forall t a. Traversable t
146183 => (Int -> a -> a -> a)
src/Data/IntMap/Strict/Refined.hs+41−4
@@ -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
src/Data/Map/Refined.hs+37−1
@@ -44,6 +44,8 @@ module Data.Map.Refined
4444 , fromSet
4545 , Common.fromMap
4646 , Common.verifyMap
47+ , fromTraversable
48+ , fromTraversableWith
4749 , fromTraversableWithKey
4850 , FromTraversableProof(..)
4951 -- * Insertion
@@ -148,7 +150,41 @@ singleton :: forall k a. k -> a -> SomeMapWith (SingletonProof 'Regular k) k a
148150singleton k v = SomeMapWith (Map $ Map.singleton k v)
149151 $ SingletonProof (unsafeKey k)
150152
151−-- | Create a map from an arbitrary traversable of key-value pairs.
153+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
154+-- repeated, the retained value is the last one in traversal order. If you're
155+-- looking for @fromList@, this is the function you want.
156+fromTraversable
157+ :: forall t k a. (Traversable t, Ord k)
158+ => t (k, a) -> SomeMapWith (FromTraversableProof 'Regular t k) k a
159+fromTraversable xs = SomeMapWith (Map m) $ FromTraversableProof proof
160+ where
161+ (m, proof) = mapAccumL
162+ (\s (k, v) -> let !s' = Map.insert k v s in (s', unsafeKey k))
163+ Map.empty
164+ xs
165+
166+-- | Create a map from an arbitrary traversable of key-value pairs, with a
167+-- function for combining values for repeated keys. The function is called as if
168+-- by 'foldl1', but flipped:
169+--
170+-- @
171+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
172+-- = 'singleton' k (f x3 (f x2 x1))
173+-- @
174+fromTraversableWith
175+ :: forall t k a. (Traversable t, Ord k)
176+ => (a -> a -> a)
177+ -> t (k, a)
178+ -> SomeMapWith (FromTraversableProof 'Regular t k) k a
179+fromTraversableWith f xs = SomeMapWith (Map m) $ FromTraversableProof proof
180+ where
181+ (m, proof) = mapAccumL
182+ (\s (k, v) -> let !s' = Map.insertWith f k v s in (s', unsafeKey k))
183+ Map.empty
184+ xs
185+
186+-- | Create a map from an arbitrary traversable of key-value pairs. Like
187+-- 'fromTraversableWith', but the combining function has access to the key.
152188fromTraversableWithKey
153189 :: forall t k a. (Traversable t, Ord k)
154190 => (k -> a -> a -> a)
src/Data/Map/Strict/Refined.hs+37−1
@@ -44,6 +44,8 @@ module Data.Map.Strict.Refined
4444 , fromSet
4545 , Common.fromMap
4646 , Common.verifyMap
47+ , fromTraversable
48+ , fromTraversableWith
4749 , fromTraversableWithKey
4850 , FromTraversableProof(..)
4951 -- * Insertion
@@ -155,7 +157,41 @@ singleton k v = SomeMapWith (Map $ Map.singleton k v)
155157fromSet :: forall s k a. KnownSet s k => (Key s k -> a) -> Map s k a
156158fromSet f = Map $ Map.fromSet (f . unsafeKey) (reflect $ Proxy @s)
157159
158−-- | Create a map from an arbitrary traversable of key-value pairs.
160+-- | Create a map from an arbitrary traversable of key-value pairs. If a key is
161+-- repeated, the retained value is the last one in traversal order. If you're
162+-- looking for @fromList@, this is the function you want.
163+fromTraversable
164+ :: forall t k a. (Traversable t, Ord k)
165+ => t (k, a) -> SomeMapWith (FromTraversableProof 'Regular t k) k a
166+fromTraversable xs = SomeMapWith (Map m) $ FromTraversableProof proof
167+ where
168+ (m, proof) = mapAccumL
169+ (\s (k, v) -> let !s' = Map.insert k v s in (s', unsafeKey k))
170+ Map.empty
171+ xs
172+
173+-- | Create a map from an arbitrary traversable of key-value pairs, with a
174+-- function for combining values for repeated keys. The function is called as if
175+-- by 'foldl1', but flipped:
176+--
177+-- @
178+-- 'fromTraversableWith' f [(k, x1), (k, x2), (k, x3)]
179+-- = 'singleton' k (f x3 (f x2 x1))
180+-- @
181+fromTraversableWith
182+ :: forall t k a. (Traversable t, Ord k)
183+ => (a -> a -> a)
184+ -> t (k, a)
185+ -> SomeMapWith (FromTraversableProof 'Regular t k) k a
186+fromTraversableWith f xs = SomeMapWith (Map m) $ FromTraversableProof proof
187+ where
188+ (m, proof) = mapAccumL
189+ (\s (k, v) -> let !s' = Map.insertWith f k v s in (s', unsafeKey k))
190+ Map.empty
191+ xs
192+
193+-- | Create a map from an arbitrary traversable of key-value pairs. Like
194+-- 'fromTraversableWith', but the combining function has access to the key.
159195fromTraversableWithKey
160196 :: forall t k a. (Traversable t, Ord k)
161197 => (k -> a -> a -> a)