@@ -1,27 +1,33 @@
11{-# OPTIONS_GHC -fno-warn-orphans #-}
22
33{-# LANGUAGE ExplicitForAll #-}
4+{-# LANGUAGE GADTs #-}
45{-# LANGUAGE KindSignatures #-}
56{-# LANGUAGE MultiParamTypeClasses #-}
67{-# LANGUAGE PolyKinds #-}
8+{-# LANGUAGE RankNTypes #-}
79{-# LANGUAGE ScopedTypeVariables #-}
810{-# LANGUAGE TypeFamilies #-}
911
1012
1113module Data.TypeRep.Vector
1214 ( TypeRepVector (..)
15+ , TF (..)
1316 , empty
1417 , insert
1518 , lookup
1619 , size
20+ , fromList
1721 ) where
1822
1923import Prelude hiding (lookup)
2024
25+import Control.Arrow ((&&&))
2126import Data.Proxy (Proxy (..))
2227import Data.Typeable (Typeable, typeRep, typeRepFingerprint)
2328import Data.Word (Word64)
2429import GHC.Base (Any)
30+import GHC.Exts (sortWith)
2531import GHC.Fingerprint (Fingerprint (..))
2632import Unsafe.Coerce (unsafeCoerce)
2733
@@ -30,105 +36,90 @@ import qualified Data.Vector.Generic as G
3036import qualified Data.Vector.Generic.Mutable as M
3137import qualified Data.Vector.Unboxed as Unboxed
3238
33−data instance Unboxed.MVector s Fingerprint = MFingerprintVector !Int (Unboxed.MVector s Word64) (Unboxed.MVector s Word64)
34−data instance Unboxed.Vector Fingerprint = FingerprintVector !Int (Unboxed.Vector Word64) (Unboxed.Vector Word64)
39+data instance Unboxed.MVector s Fingerprint = MFingerprintVector (Unboxed.MVector s Word64) (Unboxed.MVector s Word64)
40+data instance Unboxed.Vector Fingerprint = FingerprintVector (Unboxed.Vector Word64) (Unboxed.Vector Word64)
3541
3642instance Unboxed.Unbox Fingerprint
3743
3844instance M.MVector Unboxed.MVector Fingerprint where
3945 {-# INLINE basicLength #-}
40− basicLength (MFingerprintVector n _ _) = n
46+ basicLength (MFingerprintVector x _) = M.basicLength x
4147 {-# INLINE basicUnsafeSlice #-}
42− basicUnsafeSlice i m (MFingerprintVector _ a b) =
43− MFingerprintVector m (M.basicUnsafeSlice i m a) (M.basicUnsafeSlice i m b)
48+ basicUnsafeSlice i m (MFingerprintVector a b) =
49+ MFingerprintVector (M.basicUnsafeSlice i m a) (M.basicUnsafeSlice i m b)
4450 {-# INLINE basicOverlaps #-}
45− basicOverlaps (MFingerprintVector _ as1 bs1) (MFingerprintVector _ as2 bs2) =
51+ basicOverlaps (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) =
4652 M.basicOverlaps as1 as2 || M.basicOverlaps bs1 bs2
4753 {-# INLINE basicUnsafeNew #-}
48− basicUnsafeNew n_
49− = do
50− as <- M.basicUnsafeNew n_
51− bs <- M.basicUnsafeNew n_
52− return $ MFingerprintVector n_ as bs
54+ basicUnsafeNew n_ = do
55+ as <- M.basicUnsafeNew n_
56+ bs <- M.basicUnsafeNew n_
57+ return $ MFingerprintVector as bs
5358 {-# INLINE basicInitialize #-}
54− basicInitialize (MFingerprintVector _ as bs)
55− = do
56− M.basicInitialize as
57− M.basicInitialize bs
59+ basicInitialize (MFingerprintVector as bs) = do
60+ M.basicInitialize as
61+ M.basicInitialize bs
5862 {-# INLINE basicUnsafeReplicate #-}
59− basicUnsafeReplicate n_ (Fingerprint a b)
60− = do
61− as <- M.basicUnsafeReplicate n_ a
62− bs <- M.basicUnsafeReplicate n_ b
63− return $ MFingerprintVector n_ as bs
63+ basicUnsafeReplicate n_ (Fingerprint a b) = do
64+ as <- M.basicUnsafeReplicate n_ a
65+ bs <- M.basicUnsafeReplicate n_ b
66+ return $ MFingerprintVector as bs
6467 {-# INLINE basicUnsafeRead #-}
65− basicUnsafeRead (MFingerprintVector _ as bs) i_
66− = do
67− a <- M.basicUnsafeRead as i_
68− b <- M.basicUnsafeRead bs i_
69− return (Fingerprint a b)
68+ basicUnsafeRead (MFingerprintVector as bs) i_ = do
69+ a <- M.basicUnsafeRead as i_
70+ b <- M.basicUnsafeRead bs i_
71+ return (Fingerprint a b)
7072 {-# INLINE basicUnsafeWrite #-}
71− basicUnsafeWrite (MFingerprintVector _ as bs) i_ (Fingerprint a b)
72− = do
73− M.basicUnsafeWrite as i_ a
74− M.basicUnsafeWrite bs i_ b
73+ basicUnsafeWrite (MFingerprintVector as bs) i_ (Fingerprint a b) = do
74+ M.basicUnsafeWrite as i_ a
75+ M.basicUnsafeWrite bs i_ b
7576 {-# INLINE basicClear #-}
76− basicClear (MFingerprintVector _ as bs)
77− = do
78− M.basicClear as
79− M.basicClear bs
77+ basicClear (MFingerprintVector as bs) = do
78+ M.basicClear as
79+ M.basicClear bs
8080 {-# INLINE basicSet #-}
81− basicSet (MFingerprintVector _ as bs) (Fingerprint a b)
82− = do
83− M.basicSet as a
84− M.basicSet bs b
81+ basicSet (MFingerprintVector as bs) (Fingerprint a b) = do
82+ M.basicSet as a
83+ M.basicSet bs b
8584 {-# INLINE basicUnsafeCopy #-}
86− basicUnsafeCopy (MFingerprintVector _ as1 bs1) (MFingerprintVector _ as2 bs2)
87− = do
88− M.basicUnsafeCopy as1 as2
89− M.basicUnsafeCopy bs1 bs2
85+ basicUnsafeCopy (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) = do
86+ M.basicUnsafeCopy as1 as2
87+ M.basicUnsafeCopy bs1 bs2
9088 {-# INLINE basicUnsafeMove #-}
91− basicUnsafeMove (MFingerprintVector _ as1 bs1) (MFingerprintVector _ as2 bs2)
92− = do
93− M.basicUnsafeMove as1 as2
94− M.basicUnsafeMove bs1 bs2
89+ basicUnsafeMove (MFingerprintVector as1 bs1) (MFingerprintVector as2 bs2) = do
90+ M.basicUnsafeMove as1 as2
91+ M.basicUnsafeMove bs1 bs2
9592 {-# INLINE basicUnsafeGrow #-}
96− basicUnsafeGrow (MFingerprintVector n_ as bs) m_
97− = do
98− as' <- M.basicUnsafeGrow as m_
99− bs' <- M.basicUnsafeGrow bs m_
100− return $ MFingerprintVector (m_ + n_) as' bs'
93+ basicUnsafeGrow (MFingerprintVector as bs) m_ = do
94+ as' <- M.basicUnsafeGrow as m_
95+ bs' <- M.basicUnsafeGrow bs m_
96+ return $ MFingerprintVector as' bs'
10197
10298instance G.Vector Unboxed.Vector Fingerprint where
10399 {-# INLINE basicUnsafeFreeze #-}
104− basicUnsafeFreeze (MFingerprintVector n_ as bs)
105− = do
106− as' <- G.basicUnsafeFreeze as
107− bs' <- G.basicUnsafeFreeze bs
108− return $ FingerprintVector n_ as' bs'
100+ basicUnsafeFreeze (MFingerprintVector as bs) = do
101+ as' <- G.basicUnsafeFreeze as
102+ bs' <- G.basicUnsafeFreeze bs
103+ return $ FingerprintVector as' bs'
109104 {-# INLINE basicUnsafeThaw #-}
110− basicUnsafeThaw (FingerprintVector n_ as bs)
111− = do
112− as' <- G.basicUnsafeThaw as
113− bs' <- G.basicUnsafeThaw bs
114− return $ MFingerprintVector n_ as' bs'
105+ basicUnsafeThaw (FingerprintVector as bs) = do
106+ as' <- G.basicUnsafeThaw as
107+ bs' <- G.basicUnsafeThaw bs
108+ return $ MFingerprintVector as' bs'
115109 {-# INLINE basicLength #-}
116− basicLength (FingerprintVector n_ _ _) = n_
110+ basicLength (FingerprintVector x _) = G.basicLength x
117111 {-# INLINE basicUnsafeSlice #-}
118− basicUnsafeSlice i_ m_ (FingerprintVector _ as bs)
119− = FingerprintVector m_ (G.basicUnsafeSlice i_ m_ as)
120− (G.basicUnsafeSlice i_ m_ bs)
112+ basicUnsafeSlice i_ m_ (FingerprintVector as bs) =
113+ FingerprintVector (G.basicUnsafeSlice i_ m_ as) (G.basicUnsafeSlice i_ m_ bs)
121114 {-# INLINE basicUnsafeIndexM #-}
122− basicUnsafeIndexM (FingerprintVector _ as bs) i_
123− = do
124− a <- G.basicUnsafeIndexM as i_
125− b <- G.basicUnsafeIndexM bs i_
126− return (Fingerprint a b)
115+ basicUnsafeIndexM (FingerprintVector as bs) i_ = do
116+ a <- G.basicUnsafeIndexM as i_
117+ b <- G.basicUnsafeIndexM bs i_
118+ return (Fingerprint a b)
127119 {-# INLINE basicUnsafeCopy #-}
128− basicUnsafeCopy (MFingerprintVector _ as1 bs1) (FingerprintVector _ as2 bs2)
129− = do
130− G.basicUnsafeCopy as1 as2
131− G.basicUnsafeCopy bs1 bs2
120+ basicUnsafeCopy (MFingerprintVector as1 bs1) (FingerprintVector as2 bs2) = do
121+ G.basicUnsafeCopy as1 as2
122+ G.basicUnsafeCopy bs1 bs2
132123 {-# INLINE elemseq #-}
133124 elemseq _ (Fingerprint a b)
134125 = G.elemseq (undefined :: Unboxed.Vector a) a
@@ -153,7 +144,7 @@ insert = undefined
153144-- | Looks up the value at the type.
154145-- >>> let x = lookup $ insert (11 :: Int) empty
155146-- >>> x :: Maybe Int
156−-- Just 11
147+-- Just 11a Ty
157148-- >>> x :: Maybe ()
158149-- Nothing
159150lookup :: forall a f . Typeable a => TypeRepVector f -> Maybe (f a)
@@ -164,6 +155,23 @@ lookup tVect = fromAny . (anys tVect V.!)
164155size :: TypeRepVector f -> Int
165156size = Unboxed.length . fingerprints
166157
158+data TF f where
159+ TF :: Typeable a => f a -> TF f
160+
161+fromF :: Typeable a => f a -> Proxy a
162+fromF _ = Proxy
163+
164+fromList :: forall f . [TF f] -> TypeRepVector f
165+fromList tfs = TypeRepVect (Unboxed.fromList fps) (V.fromList ans)
166+ where
167+ (fps, ans) = unzip $ sortWith fst $ map (fp &&& an) tfs
168+
169+ fp :: TF f -> Fingerprint
170+ fp (TF x) = typeRepFingerprint $ typeRep $ fromF x
171+
172+ an :: TF f -> Any
173+ an (TF x) = unsafeCoerce x
174+
167175-- | Returns the index is found.
168176binarySearch :: Fingerprint -> Unboxed.Vector Fingerprint -> Maybe Int
169177binarySearch fp fpVect =