@@ -46,15 +46,18 @@ import qualified Data.IntMap.Strict as IM
4646import qualified Data.Vector as V
4747import qualified Data.Vector.Unboxed as Unboxed
4848
49+-- | Map-like data structure that keeps types as keys.
4950data TypeRepMap (f :: k -> Type) = TypeRepMap
5051 { fingerprintAs :: Unboxed.Vector Word64
5152 , fingerprintBs :: Unboxed.Vector Word64
5253 , anys :: V.Vector Any
5354 }
5455
56+-- | Shows only 'Fingerprint's.
5557instance Show (TypeRepMap f) where
5658 show = show . toFps
5759
60+-- | Returnes the list of 'Fingerprint's from 'TypeRepMap'.
5861toFps :: TypeRepMap f -> [Fingerprint]
5962toFps TypeRepMap{..} = zipWith Fingerprint
6063 (Unboxed.toList fingerprintAs)
@@ -81,12 +84,15 @@ insert x = fromListPairs . addX . toPairList
8184 addX l = pairX : filter ((/= fpX) . fst) l
8285{-# INLINE insert #-}
8386
84−-- | Looks up the value at the type.
85−-- >>> let x = lookup $ insert (11 :: Int) empty
86−-- >>> x :: Maybe Int
87−-- Just 11
88−-- >>> x :: Maybe ()
89−-- Nothing
87+{- | Looks up the value at the type.
88+
89+>>> let x = lookup $ insert (Identity (11 :: Int)) empty
90+>>> x :: Maybe (Identity Int)
91+Just (Identity 11)
92+>>> x :: Maybe (Identity ())
93+Nothing
94+
95+-}
9096lookup :: forall a f . Typeable a => TypeRepMap f -> Maybe (f a)
9197lookup tVect = fromAny . (anys tVect V.!)
9298 <$> cachedBinarySearch (typeRepFingerprint $ typeRep $ Proxy @a)
@@ -97,6 +103,7 @@ lookup tVect = fromAny . (anys tVect V.!)
97103-- | Returns the size of the 'TypeRepMap'.
98104size :: TypeRepMap f -> Int
99105size = Unboxed.length . fingerprintAs
106+{-# INLINE size #-}
100107
101108-- | Binary searched based on this article
102109-- http://bannalia.blogspot.com/2015/06/cache-friendly-binary-search.html
@@ -125,12 +132,29 @@ cachedBinarySearch (Fingerprint (W64# a) (W64# b)) fpAs fpBs = inline (go 0#)
125132-- Functions for testing and benchmarking
126133----------------------------------------------------------------------------
127134
135+-- | Existential wrapper around 'Typeable' indexed by @f@ type parameter.
136+-- Useful for 'TypeRepMap' structure creation form list of 'TF's.
128137data TF f where
129138 TF :: Typeable a => f a -> TF f
130139
131140instance Show (TF f) where
132141 show (TF tf) = show $ calcFp tf
133142
143+{- | Creates 'TypeRepMap' from a list of 'TF's.
144+
145+>>> size $ fromList [TF $ Identity True, TF $ Identity 'a']
146+2
147+
148+-}
149+fromList :: forall f . [TF f] -> TypeRepMap f
150+fromList = fromListPairs . map (fp &&& an)
151+ where
152+ fp :: TF f -> Fingerprint
153+ fp (TF x) = calcFp x
154+
155+ an :: TF f -> Any
156+ an (TF x) = unsafeCoerce x
157+
134158fromF :: Typeable a => f a -> Proxy a
135159fromF _ = Proxy
136160
@@ -143,15 +167,6 @@ fromListPairs kvs = TypeRepMap (Unboxed.fromList fpAs) (Unboxed.fromList fpBs) (
143167 (fpAs, fpBs) = unzip $ map (\(Fingerprint a b) -> (a, b)) fps
144168 (fps, ans) = unzip $ fromSortedList $ sortWith fst $ nubPairs kvs
145169
146−fromList :: forall f . [TF f] -> TypeRepMap f
147−fromList = fromListPairs . map (fp &&& an)
148− where
149− fp :: TF f -> Fingerprint
150− fp (TF x) = calcFp x
151−
152− an :: TF f -> Any
153− an (TF x) = unsafeCoerce x
154−
155170nubPairs :: (Eq a) => [(a, b)] -> [(a, b)]
156171nubPairs = nubBy ((==) `on` fst)
157172