on main help sign in
[#46] Improve Show instance, add keys (#49)
commit30686c78abd4d131ac3f8ebd30802465404507dd authorVeronika Romashkina <vrom911@gmail.com> dateSun 19 Aug 2018, 11:47 (8 years ago) parent0abe416
5 files changed+36−11
CHANGELOG.md+6 src/Data/TMap.hs+7 src/Data/TypeRepMap.hs+1 src/Data/TypeRepMap/Internal.hs+21−10 typerep-map.cabal+1−1
CHANGELOG.md+6
@@ -4,6 +4,12 @@ Change log
44`typerep-map` uses [PVP Versioning][1].
55The change log is available [on GitHub][2].
66
7+# 0.3.0
8+
9+* [#43](https://github.com/kowainik/typerep-map/issues/43):
10+ Make `Show` instance for `TypeRepMap` show keys.
11+ Add `keys` function.
12+
713# 0.2.0
814
915* [#43](https://github.com/kowainik/typerep-map/issues/43):
src/Data/TMap.hs+7
@@ -39,6 +39,7 @@ module Data.TMap
3939 , lookup
4040 , member
4141 , size
42+ , keys
4243 ) where
4344
4445import Prelude hiding (lookup, map)
@@ -46,6 +47,7 @@ import Prelude hiding (lookup, map)
4647import Data.Functor.Identity (Identity (..))
4748import Data.Typeable (Typeable)
4849import GHC.Exts (coerce)
50+import Type.Reflection (SomeTypeRep)
4951
5052import qualified Data.TypeRepMap as F
5153
@@ -148,6 +150,11 @@ size :: TMap -> Int
148150size = F.size
149151{-# INLINE size #-}
150152
153+-- | Returns the list of 'SomeTypeRep's from keys.
154+keys :: TMap -> [SomeTypeRep]
155+keys = F.keys
156+{-# INLINE keys #-}
157+
151158-- | Map a function over the values.
152159map :: (forall a. Typeable a => a -> a) -> TMap -> TMap
153160map f = F.hoistWithKey (fIdentity f)
src/Data/TypeRepMap.hs+1
@@ -61,6 +61,7 @@ module Data.TypeRepMap
6161 , lookup
6262 , member
6363 , size
64+ , keys
6465
6566 -- * 'IsList'
6667 , WrapTypeable (..)
src/Data/TypeRepMap/Internal.hs+21−10
@@ -27,7 +27,7 @@ import Control.Monad.Zip (mzip)
2727import Data.Function (on)
2828import Data.IntMap.Strict (IntMap)
2929import Data.Kind (Type)
30−import Data.List (nubBy)
30+import Data.List (intercalate, nubBy)
3131import Data.Maybe (fromJust)
3232import Data.Primitive.Array (Array, indexArray, mapArray')
3333import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
@@ -37,7 +37,7 @@ import GHC.Exts (IsList (..), inline, sortWith)
3737import GHC.Fingerprint (Fingerprint (..))
3838import GHC.Prim (eqWord#, ltWord#)
3939import GHC.Word (Word64 (..))
40−import Type.Reflection (TypeRep, Typeable, typeRep, withTypeable)
40+import Type.Reflection (SomeTypeRep (..), TypeRep, Typeable, typeRep, withTypeable)
4141import Type.Reflection.Unsafe (typeRepFingerprint)
4242import Unsafe.Coerce (unsafeCoerce)
4343
@@ -70,14 +70,17 @@ data TypeRepMap (f :: k -> Type) =
7070 TypeRepMap
7171 { fingerprintAs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ first components of key fingerprints
7272 , fingerprintBs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ second components of key fingerprints
73− , anys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
74− , keys :: {-# UNPACK #-} !(Array Any) -- ^ typerep keys
73+ , trAnys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
74+ , trKeys :: {-# UNPACK #-} !(Array Any) -- ^ typerep keys
7575 }
7676 -- ^ an unsafe constructor for 'TypeRepMap'
7777
78−-- | Shows only 'Fingerprint's.
78+-- | Shows only keys.
7979instance Show (TypeRepMap f) where
80− show = show . toFingerprints
80+ show TypeRepMap{..} = "TypeRepMap [" ++ showKeys ++ "]"
81+ where
82+ showKeys :: String
83+ showKeys = intercalate ", " $ toList $ mapArray' (show . anyToTypeRep) trKeys
8184
8285-- | Uses 'union' to combine 'TypeRepMap's.
8386instance Semigroup (TypeRepMap f) where
@@ -237,7 +240,7 @@ Just (Identity 11)
237240Nothing
238241-}
239242lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
240−lookup tVect = fromAny . (anys tVect `indexArray`)
243+lookup tVect = fromAny . (trAnys tVect `indexArray`)
241244 <$> cachedBinarySearch (typeFp @a)
242245 (fingerprintAs tVect)
243246 (fingerprintBs tVect)
@@ -248,6 +251,11 @@ size :: TypeRepMap f -> Int
248251size = sizeofPrimArray . fingerprintAs
249252{-# INLINE size #-}
250253
254+-- | Return the list of 'SomeTypeRep' from the keys.
255+keys :: TypeRepMap f -> [SomeTypeRep]
256+keys TypeRepMap{..} = SomeTypeRep . anyToTypeRep <$> toList trKeys
257+{-# INLINE keys #-}
258+
251259-- | Binary searched based on this article
252260-- http://bannalia.blogspot.com/2015/06/cache-friendly-binary-search.html
253261-- with modification for our two-vector search case.
@@ -281,12 +289,15 @@ toAny = unsafeCoerce
281289fromAny :: Any -> f a
282290fromAny = unsafeCoerce
283291
292+anyToTypeRep :: Any -> TypeRep f
293+anyToTypeRep = unsafeCoerce
294+
284295typeFp :: forall a . Typeable a => Fingerprint
285296typeFp = typeRepFingerprint $ typeRep @a
286297{-# INLINE typeFp #-}
287298
288299toTriples :: TypeRepMap f -> [(Fingerprint, Any, Any)]
289−toTriples tm = zip3 (toFingerprints tm) (GHC.toList $ anys tm) (GHC.toList $ keys tm)
300+toTriples tm = zip3 (toFingerprints tm) (GHC.toList $ trAnys tm) (GHC.toList $ trKeys tm)
290301
291302deleteByFst :: Eq a => a -> [(a, b, c)] -> [(a, b, c)]
292303deleteByFst x = filter ((/= x) . fst3)
@@ -315,8 +326,8 @@ prop> fromList . toList == 'id'
315326
316327Creates 'TypeRepMap' from a list of 'WrapTypeable's.
317328
318−>>> size $ fromList [WrapTypeable $ Identity True, WrapTypeable $ Identity 'a']
319−2
329+>>> show $ fromList [WrapTypeable $ Identity True, WrapTypeable $ Identity 'a']
330+TypeRepMap [Bool, Char]
320331
321332
322333-}
typerep-map.cabal+1−1
@@ -1,5 +1,5 @@
11name: typerep-map
2−version: 0.2.0
2+version: 0.3.0
33synopsis: Efficient implementation of a dependent map with types as keys
44description:
55 A dependent map from type representations to values of these types.