on main help sign in
[#39] Add hoistWithKey and map for TMap (#45)
0abe416Veronika Romashkina
CHANGELOG.md+3
@@ -9,6 +9,9 @@ The change log is available [on GitHub][2].
9* [#43](https://github.com/kowainik/typerep-map/issues/43):
9* [#43](https://github.com/kowainik/typerep-map/issues/43):
10 Implement `IsList` instance for `TypeRepMap`.
10 Implement `IsList` instance for `TypeRepMap`.
11 Add `hoistA` function.
11 Add `hoistA` function.
12+* [#39](https://github.com/kowainik/typerep-map/issues/39):
13+ Implement `hoistWithKey` function.
14+ Add `map` function for `TMap`.
12* Drop support for `ghc-8.0.2`.
15* Drop support for `ghc-8.0.2`.
13
16
14# 0.1.0
17# 0.1.0
src/Data/TMap.hs+10−1
@@ -33,6 +33,7 @@ module Data.TMap
33 , delete
33 , delete
34 , unionWith
34 , unionWith
35 , union
35 , union
36+ , map
36
37
37 -- * Query
38 -- * Query
38 , lookup
39 , lookup
@@ -40,7 +41,7 @@ module Data.TMap
40 , size
41 , size
41 ) where
42 ) where
42
43
43−import Prelude hiding (lookup)
44+import Prelude hiding (lookup, map)
44
45
45import Data.Functor.Identity (Identity (..))
46import Data.Functor.Identity (Identity (..))
46import Data.Typeable (Typeable)
47import Data.Typeable (Typeable)
@@ -146,3 +147,11 @@ member = F.member @a @Identity
146size :: TMap -> Int
147size :: TMap -> Int
147size = F.size
148size = F.size
148{-# INLINE size #-}
149{-# INLINE size #-}
150+
151+-- | Map a function over the values.
152+map :: (forall a. Typeable a => a -> a) -> TMap -> TMap
153+map f = F.hoistWithKey (fIdentity f)
154+ where
155+ fIdentity :: forall a. Typeable a => (a -> a) -> Identity a -> Identity a
156+ fIdentity = coerce
157+{-# INLINE map #-}
src/Data/TypeRepMap.hs+1
@@ -53,6 +53,7 @@ module Data.TypeRepMap
53 , delete
53 , delete
54 , hoist
54 , hoist
55 , hoistA
55 , hoistA
56+ , hoistWithKey
56 , unionWith
57 , unionWith
57 , union
58 , union
58
59
src/Data/TypeRepMap/Internal.hs+12−1
@@ -23,6 +23,7 @@ module Data.TypeRepMap.Internal where
23
23
24import Prelude hiding (lookup)
24import Prelude hiding (lookup)
25
25
26+import Control.Monad.Zip (mzip)
26import Data.Function (on)
27import Data.Function (on)
27import Data.IntMap.Strict (IntMap)
28import Data.IntMap.Strict (IntMap)
28import Data.Kind (Type)
29import Data.Kind (Type)
@@ -36,7 +37,7 @@ import GHC.Exts (IsList (..), inline, sortWith)
36import GHC.Fingerprint (Fingerprint (..))
37import GHC.Fingerprint (Fingerprint (..))
37import GHC.Prim (eqWord#, ltWord#)
38import GHC.Prim (eqWord#, ltWord#)
38import GHC.Word (Word64 (..))
39import GHC.Word (Word64 (..))
39−import Type.Reflection (Typeable, typeRep, withTypeable)
40+import Type.Reflection (TypeRep, Typeable, typeRep, withTypeable)
40import Type.Reflection.Unsafe (typeRepFingerprint)
41import Type.Reflection.Unsafe (typeRepFingerprint)
41import Unsafe.Coerce (unsafeCoerce)
42import Unsafe.Coerce (unsafeCoerce)
42
43
@@ -180,6 +181,16 @@ hoistA f (TypeRepMap as bs (toList -> ans) ks) = (\l -> TypeRepMap as bs (fromLi
180 <$> traverse (f . fromAny) ans
181 <$> traverse (f . fromAny) ans
181{-# INLINE hoistA #-}
182{-# INLINE hoistA #-}
182
183
184+hoistWithKey :: forall f g. (forall x. Typeable x => f x -> g x) -> TypeRepMap f -> TypeRepMap g
185+hoistWithKey f (TypeRepMap as bs ans ks) = TypeRepMap as bs newAns ks
186+ where
187+ newAns = mapArray' mapAns (mzip ans ks)
188+ mapAns (a, k) = toAny $ withTr (unsafeCoerce k) $ fromAny a
189+
190+ withTr :: forall x. TypeRep x -> f x -> g x
191+ withTr t = withTypeable t f
192+{-# INLINE hoistWithKey #-}
193+
183-- | The union of two 'TypeRepMap's using a combining function.
194-- | The union of two 'TypeRepMap's using a combining function.
184unionWith :: (forall x. f x -> f x -> f x) -> TypeRepMap f -> TypeRepMap f -> TypeRepMap f
195unionWith :: (forall x. f x -> f x -> f x) -> TypeRepMap f -> TypeRepMap f -> TypeRepMap f
185unionWith f m1 m2 = fromTriples
196unionWith f m1 m2 = fromTriples