on main help sign in
[#39] Add hoistWithKey and map for TMap (#45)

* [#39] Add hoistWithKey and map for TMap * Use coerce instead of fmap

commit0abe4165216ad15e68a8063b87a9eb9c35bf23d7 authorVeronika Romashkina <vrom911@gmail.com> dateSat 28 Jul 2018, 12:13 (8 years ago) parent290856c
4 files changed+26−2
CHANGELOG.md+3 src/Data/TMap.hs+10−1 src/Data/TypeRepMap.hs+1 src/Data/TypeRepMap/Internal.hs+12−1
CHANGELOG.md+3
@@ -9,6 +9,9 @@ The change log is available [on GitHub][2].
99* [#43](https://github.com/kowainik/typerep-map/issues/43):
1010 Implement `IsList` instance for `TypeRepMap`.
1111 Add `hoistA` function.
12+* [#39](https://github.com/kowainik/typerep-map/issues/39):
13+ Implement `hoistWithKey` function.
14+ Add `map` function for `TMap`.
1215* Drop support for `ghc-8.0.2`.
1316
1417# 0.1.0
src/Data/TMap.hs+10−1
@@ -33,6 +33,7 @@ module Data.TMap
3333 , delete
3434 , unionWith
3535 , union
36+ , map
3637
3738 -- * Query
3839 , lookup
@@ -40,7 +41,7 @@ module Data.TMap
4041 , size
4142 ) where
4243
43−import Prelude hiding (lookup)
44+import Prelude hiding (lookup, map)
4445
4546import Data.Functor.Identity (Identity (..))
4647import Data.Typeable (Typeable)
@@ -146,3 +147,11 @@ member = F.member @a @Identity
146147size :: TMap -> Int
147148size = F.size
148149{-# 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
5353 , delete
5454 , hoist
5555 , hoistA
56+ , hoistWithKey
5657 , unionWith
5758 , union
5859
src/Data/TypeRepMap/Internal.hs+12−1
@@ -23,6 +23,7 @@ module Data.TypeRepMap.Internal where
2323
2424import Prelude hiding (lookup)
2525
26+import Control.Monad.Zip (mzip)
2627import Data.Function (on)
2728import Data.IntMap.Strict (IntMap)
2829import Data.Kind (Type)
@@ -36,7 +37,7 @@ import GHC.Exts (IsList (..), inline, sortWith)
3637import GHC.Fingerprint (Fingerprint (..))
3738import GHC.Prim (eqWord#, ltWord#)
3839import GHC.Word (Word64 (..))
39−import Type.Reflection (Typeable, typeRep, withTypeable)
40+import Type.Reflection (TypeRep, Typeable, typeRep, withTypeable)
4041import Type.Reflection.Unsafe (typeRepFingerprint)
4142import Unsafe.Coerce (unsafeCoerce)
4243
@@ -180,6 +181,16 @@ hoistA f (TypeRepMap as bs (toList -> ans) ks) = (\l -> TypeRepMap as bs (fromLi
180181 <$> traverse (f . fromAny) ans
181182{-# INLINE hoistA #-}
182183
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+
183194-- | The union of two 'TypeRepMap's using a combining function.
184195unionWith :: (forall x. f x -> f x -> f x) -> TypeRepMap f -> TypeRepMap f -> TypeRepMap f
185196unionWith f m1 m2 = fromTriples