@@ -27,7 +27,7 @@ import Control.Monad.Zip (mzip)
27import Data.Function (on)
27import Data.Function (on)
28import Data.IntMap.Strict (IntMap)
28import Data.IntMap.Strict (IntMap)
29import Data.Kind (Type)
29import Data.Kind (Type)
30−import Data.List (nubBy)
30+import Data.List (intercalate, nubBy)
31import Data.Maybe (fromJust)
31import Data.Maybe (fromJust)
32import Data.Primitive.Array (Array, indexArray, mapArray')
32import Data.Primitive.Array (Array, indexArray, mapArray')
33import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
33import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
@@ -37,7 +37,7 @@ import GHC.Exts (IsList (..), inline, sortWith)
37import GHC.Fingerprint (Fingerprint (..))
37import GHC.Fingerprint (Fingerprint (..))
38import GHC.Prim (eqWord#, ltWord#)
38import GHC.Prim (eqWord#, ltWord#)
39import GHC.Word (Word64 (..))
39import GHC.Word (Word64 (..))
40−import Type.Reflection (TypeRep, Typeable, typeRep, withTypeable)
40+import Type.Reflection (SomeTypeRep (..), TypeRep, Typeable, typeRep, withTypeable)
41import Type.Reflection.Unsafe (typeRepFingerprint)
41import Type.Reflection.Unsafe (typeRepFingerprint)
42import Unsafe.Coerce (unsafeCoerce)
42import Unsafe.Coerce (unsafeCoerce)
@@ -70,14 +70,17 @@ data TypeRepMap (f :: k -> Type) =
70 TypeRepMap
70 TypeRepMap
71 { fingerprintAs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ first components of key fingerprints
71 { fingerprintAs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ first components of key fingerprints
72 , fingerprintBs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ second components of key fingerprints
72 , fingerprintBs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ second components of key fingerprints
73− , anys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
73+ , trAnys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
74− , keys :: {-# UNPACK #-} !(Array Any) -- ^ typerep keys
74+ , trKeys :: {-# UNPACK #-} !(Array Any) -- ^ typerep keys
76 -- ^ an unsafe constructor for 'TypeRepMap'
76 -- ^ an unsafe constructor for 'TypeRepMap'
78−-- | Shows only 'Fingerprint's.
78+-- | Shows only keys.
79instance Show (TypeRepMap f) where
79instance Show (TypeRepMap f) where
80− show = show . toFingerprints
80+ show TypeRepMap{..} = "TypeRepMap [" ++ showKeys ++ "]"
83+ showKeys = intercalate ", " $ toList $ mapArray' (show . anyToTypeRep) trKeys
82-- | Uses 'union' to combine 'TypeRepMap's.
85-- | Uses 'union' to combine 'TypeRepMap's.
83instance Semigroup (TypeRepMap f) where
86instance Semigroup (TypeRepMap f) where
@@ -237,7 +240,7 @@ Just (Identity 11)
239lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
242lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
240−lookup tVect = fromAny . (anys tVect `indexArray`)
243+lookup tVect = fromAny . (trAnys tVect `indexArray`)
241 <$> cachedBinarySearch (typeFp @a)
244 <$> cachedBinarySearch (typeFp @a)
242 (fingerprintAs tVect)
245 (fingerprintAs tVect)
243 (fingerprintBs tVect)
246 (fingerprintBs tVect)
@@ -248,6 +251,11 @@ size :: TypeRepMap f -> Int
248size = sizeofPrimArray . fingerprintAs
251size = sizeofPrimArray . fingerprintAs
249{-# INLINE size #-}
252{-# INLINE size #-}
254+-- | Return the list of 'SomeTypeRep' from the keys.
255+keys :: TypeRepMap f -> [SomeTypeRep]
256+keys TypeRepMap{..} = SomeTypeRep . anyToTypeRep <$> toList trKeys
251-- | Binary searched based on this article
259-- | Binary searched based on this article
252-- http://bannalia.blogspot.com/2015/06/cache-friendly-binary-search.html
260-- http://bannalia.blogspot.com/2015/06/cache-friendly-binary-search.html
253-- with modification for our two-vector search case.
261-- with modification for our two-vector search case.
@@ -281,12 +289,15 @@ toAny = unsafeCoerce
281fromAny :: Any -> f a
289fromAny :: Any -> f a
282fromAny = unsafeCoerce
290fromAny = unsafeCoerce
292+anyToTypeRep :: Any -> TypeRep f
293+anyToTypeRep = unsafeCoerce
284typeFp :: forall a . Typeable a => Fingerprint
295typeFp :: forall a . Typeable a => Fingerprint
285typeFp = typeRepFingerprint $ typeRep @a
296typeFp = typeRepFingerprint $ typeRep @a
286{-# INLINE typeFp #-}
297{-# INLINE typeFp #-}
288toTriples :: TypeRepMap f -> [(Fingerprint, Any, Any)]
299toTriples :: 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)
291deleteByFst :: Eq a => a -> [(a, b, c)] -> [(a, b, c)]
302deleteByFst :: Eq a => a -> [(a, b, c)] -> [(a, b, c)]
292deleteByFst x = filter ((/= x) . fst3)
303deleteByFst x = filter ((/= x) . fst3)
@@ -315,8 +326,8 @@ prop> fromList . toList == 'id'
316Creates 'TypeRepMap' from a list of 'WrapTypeable's.
327Creates 'TypeRepMap' from a list of 'WrapTypeable's.
318−>>> size $ fromList [WrapTypeable $ Identity True, WrapTypeable $ Identity 'a']
329+>>> show $ fromList [WrapTypeable $ Identity True, WrapTypeable $ Identity 'a']
319−2
330+TypeRepMap [Bool, Char]