1{-# LANGUAGE ExplicitForAll #-}
2{-# LANGUAGE KindSignatures #-}
3{-# LANGUAGE PolyKinds #-}
4{-# LANGUAGE ScopedTypeVariables #-}
5{-# LANGUAGE TypeFamilies #-}
8module Data.TypeRep.Vector
16import Prelude hiding (lookup)
18import Data.Proxy (Proxy (..))
19import Data.Typeable (TypeRep, Typeable, typeRep, typeRepFingerprint)
20import Data.Word (Word64)
22import GHC.Fingerprint (Fingerprint (..))
23import Unsafe.Coerce (unsafeCoerce)
25import qualified Data.Vector as V
26import qualified Data.Vector.Unboxed as Unboxed
28type FingerprintPair = (Word64, Word64)
30data TypeRepVector f = TypeRepVect
31 { fingerprints :: Unboxed.Vector FingerprintPair
32 , anys :: V.Vector Any
35fromFingerprint :: Fingerprint -> FingerprintPair
36fromFingerprint (Fingerprint x y) = (x, y)
38typeRepToPair :: TypeRep -> FingerprintPair
39typeRepToPair = fromFingerprint . typeRepFingerprint
42empty :: TypeRepVector f
43empty = TypeRepVect mempty mempty
45-- | Inserts the value with its type as a key.
46insert :: forall a f . Typeable a => a -> TypeRepVector f -> TypeRepVector f
49-- | Looks up the value at the type.
50-- >>> let x = lookup $ insert (11 :: Int) empty
55lookup :: forall a f . Typeable a => TypeRepVector f -> Maybe (f a)
56lookup tVect = case binarySearch (typeRepToPair (typeRep (Proxy :: Proxy a))) (fingerprints tVect) of
57 Just ind -> Just $ unsafeCoerce $ (anys tVect) V.! ind
60-- | Returns the size of the 'TypeRepVect'.
61size :: TypeRepVector f -> Int
62size = Unboxed.length . fingerprints
64-- | Returns the index is found.
65binarySearch :: FingerprintPair -> Unboxed.Vector FingerprintPair -> Maybe Int
66binarySearch fp fpVect =
67 let ind = binSearchHelp (-1) (Unboxed.length fpVect) in
68 if fp == (fpVect Unboxed.! ind) then Just ind else Nothing
70 binSearchHelp :: Int -> Int -> Int
71 binSearchHelp l r = if l < r - 1
73 let m = (l + r) `div` 2 in
74 if fpVect Unboxed.! m < fp
75 then binSearchHelp m r
76 else binSearchHelp l m )
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list