on main help sign in
[#43] IsList instance (#44)
290856cVeronika Romashkina
.travis.yml−11
@@ -15,17 +15,6 @@ matrix:
15
15
16 include:
16 include:
17
17
18− - ghc: 8.0.2
19− env: GHCVER='8.0.2' CABALVER='head' ALLOWNEWER='--allow-newer'
20− os: linux
21− addons:
22− apt:
23− sources:
24− - hvr-ghc
25− packages:
26− - ghc-8.0.2
27− - cabal-install-head
28−
29 - ghc: 8.2.2
18 - ghc: 8.2.2
30 env: GHCVER='8.2.2' CABALVER='head'
19 env: GHCVER='8.2.2' CABALVER='head'
31 os: linux
20 os: linux
CHANGELOG.md+7
@@ -4,6 +4,13 @@ Change log
4`typerep-map` uses [PVP Versioning][1].
4`typerep-map` uses [PVP Versioning][1].
5The change log is available [on GitHub][2].
5The change log is available [on GitHub][2].
6
6
7+# 0.2.0
8+
9+* [#43](https://github.com/kowainik/typerep-map/issues/43):
10+ Implement `IsList` instance for `TypeRepMap`.
11+ Add `hoistA` function.
12+* Drop support for `ghc-8.0.2`.
13+
7# 0.1.0
14# 0.1.0
8
15
9* Initially created.
16* Initially created.
benchmark/CacheMap.hs+6−5
@@ -19,9 +19,10 @@ import Prelude hiding (lookup)
19import Data.Maybe (fromJust)
19import Data.Maybe (fromJust)
20import Data.Proxy (Proxy (..))
20import Data.Proxy (Proxy (..))
21import Data.Typeable (Typeable)
21import Data.Typeable (Typeable)
22+import GHC.Exts (fromList)
22import GHC.TypeLits
23import GHC.TypeLits
23
24
24−import Data.TypeRepMap.Internal (TF (..), TypeRepMap (..), fromList, lookup)
25+import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), lookup)
25
26
26benchCacheMap :: Benchmark
27benchCacheMap :: Benchmark
27benchCacheMap = bgroup "vector optimal cache"
28benchCacheMap = bgroup "vector optimal cache"
@@ -46,7 +47,7 @@ bigMap = fromList $ buildBigMap 10000 (Proxy :: Proxy 0) []
46buildBigMap :: forall a . (KnownNat a)
47buildBigMap :: forall a . (KnownNat a)
47 => Int
48 => Int
48 -> Proxy (a :: Nat)
49 -> Proxy (a :: Nat)
49− -> [TF (Proxy :: Nat -> *)]
50+ -> [WrapTypeable (Proxy :: Nat -> *)]
50− -> [TF (Proxy :: Nat -> *)]
51+ -> [WrapTypeable (Proxy :: Nat -> *)]
51−buildBigMap 1 x = (TF x :)
52+buildBigMap 1 x = (WrapTypeable x :)
52−buildBigMap n x = (TF x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1))
53+buildBigMap n x = (WrapTypeable x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1))
src/Data/TypeRepMap.hs+3
@@ -52,6 +52,7 @@ module Data.TypeRepMap
52 , insert
52 , insert
53 , delete
53 , delete
54 , hoist
54 , hoist
55+ , hoistA
55 , unionWith
56 , unionWith
56 , union
57 , union
57
58
@@ -60,6 +61,8 @@ module Data.TypeRepMap
60 , member
61 , member
61 , size
62 , size
62
63
64+ -- * 'IsList'
65+ , WrapTypeable (..)
63 ) where
66 ) where
64
67
65import Data.TypeRepMap.Internal
68import Data.TypeRepMap.Internal
src/Data/TypeRepMap/Internal.hs+75−46
@@ -9,6 +9,7 @@
9{-# LANGUAGE Rank2Types #-}
9{-# LANGUAGE Rank2Types #-}
10{-# LANGUAGE TypeFamilies #-}
10{-# LANGUAGE TypeFamilies #-}
11{-# LANGUAGE TypeInType #-}
11{-# LANGUAGE TypeInType #-}
12+{-# LANGUAGE ViewPatterns #-}
12
13
13-- {-# OPTIONS_GHC -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes #-}
14-- {-# OPTIONS_GHC -ddump-simpl -dsuppress-idinfo -dsuppress-coercions -dsuppress-type-applications -dsuppress-uniques -dsuppress-module-prefixes #-}
14
15
@@ -22,7 +23,6 @@ module Data.TypeRepMap.Internal where
22
23
23import Prelude hiding (lookup)
24import Prelude hiding (lookup)
24
25
25−import Control.Arrow ((&&&))
26import Data.Function (on)
26import Data.Function (on)
27import Data.IntMap.Strict (IntMap)
27import Data.IntMap.Strict (IntMap)
28import Data.Kind (Type)
28import Data.Kind (Type)
@@ -30,14 +30,14 @@ import Data.List (nubBy)
30import Data.Maybe (fromJust)
30import Data.Maybe (fromJust)
31import Data.Primitive.Array (Array, indexArray, mapArray')
31import Data.Primitive.Array (Array, indexArray, mapArray')
32import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
32import Data.Primitive.PrimArray (PrimArray, indexPrimArray, sizeofPrimArray)
33−import Data.Proxy (Proxy (..))
34import Data.Semigroup (Semigroup (..))
33import Data.Semigroup (Semigroup (..))
35−import Data.Typeable (Typeable, typeRep, typeRepFingerprint)
36import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
34import GHC.Base (Any, Int (..), Int#, (*#), (+#), (<#))
37−import GHC.Exts (inline, sortWith)
35+import GHC.Exts (IsList (..), inline, sortWith)
38import GHC.Fingerprint (Fingerprint (..))
36import GHC.Fingerprint (Fingerprint (..))
39import GHC.Prim (eqWord#, ltWord#)
37import GHC.Prim (eqWord#, ltWord#)
40import GHC.Word (Word64 (..))
38import GHC.Word (Word64 (..))
39+import Type.Reflection (Typeable, typeRep, withTypeable)
40+import Type.Reflection.Unsafe (typeRepFingerprint)
41import Unsafe.Coerce (unsafeCoerce)
41import Unsafe.Coerce (unsafeCoerce)
42
42
43import qualified Data.IntMap.Strict as IM
43import qualified Data.IntMap.Strict as IM
@@ -70,6 +70,7 @@ data TypeRepMap (f :: k -> Type) =
70 { fingerprintAs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ first components of key fingerprints
70 { fingerprintAs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ first components of key fingerprints
71 , fingerprintBs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ second components of key fingerprints
71 , fingerprintBs :: {-# UNPACK #-} !(PrimArray Word64) -- ^ second components of key fingerprints
72 , anys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
72 , anys :: {-# UNPACK #-} !(Array Any) -- ^ values stored in the map
73+ , keys :: {-# UNPACK #-} !(Array Any) -- ^ typerep keys
73 }
74 }
74 -- ^ an unsafe constructor for 'TypeRepMap'
75 -- ^ an unsafe constructor for 'TypeRepMap'
75
76
@@ -84,7 +85,7 @@ instance Semigroup (TypeRepMap f) where
84 {-# INLINE (<>) #-}
85 {-# INLINE (<>) #-}
85
86
86instance Monoid (TypeRepMap f) where
87instance Monoid (TypeRepMap f) where
87− mempty = TypeRepMap mempty mempty mempty
88+ mempty = TypeRepMap mempty mempty mempty mempty
88 mappend = (<>)
89 mappend = (<>)
89 {-# INLINE mempty #-}
90 {-# INLINE mempty #-}
90 {-# INLINE mappend #-}
91 {-# INLINE mappend #-}
@@ -127,13 +128,13 @@ prop> member @a (insert (x :: f a) tm) == True
127
128
128-}
129-}
129insert :: forall a f . Typeable a => f a -> TypeRepMap f -> TypeRepMap f
130insert :: forall a f . Typeable a => f a -> TypeRepMap f -> TypeRepMap f
130−insert x = fromListPairs . addX . toPairList
131+insert x = fromTriples . addX . toTriples
131 where
132 where
132− pairX :: (Fingerprint, Any)
133+ tripleX :: (Fingerprint, Any, Any)
133− pairX@(fpX, _) = (calcFp x, toAny x)
134+ tripleX@(fpX, _, _) = (calcFp @a, toAny x, unsafeCoerce $ typeRep @a)
134
135
135− addX :: [(Fingerprint, Any)] -> [(Fingerprint, Any)]
136+ addX :: [(Fingerprint, Any, Any)] -> [(Fingerprint, Any, Any)]
136− addX l = pairX : deleteByFst fpX l
137+ addX l = tripleX : deleteByFst fpX l
137{-# INLINE insert #-}
138{-# INLINE insert #-}
138
139
139-- Extract the kind of a type. We use it to work around lack of syntax for
140-- Extract the kind of a type. We use it to work around lack of syntax for
@@ -154,7 +155,7 @@ False
154True
155True
155-}
156-}
156delete :: forall a (f :: KindOf a -> Type) . Typeable a => TypeRepMap f -> TypeRepMap f
157delete :: forall a (f :: KindOf a -> Type) . Typeable a => TypeRepMap f -> TypeRepMap f
157−delete = fromListPairs . deleteByFst (typeFp @a) . toPairList
158+delete = fromTriples . deleteByFst (typeFp @a) . toTriples
158{-# INLINE delete #-}
159{-# INLINE delete #-}
159
160
160{- | Map over the elements of a 'TypeRepMap'.
161{- | Map over the elements of a 'TypeRepMap'.
@@ -171,19 +172,30 @@ Just [True]
171Just "a"
172Just "a"
172-}
173-}
173hoist :: (forall x. f x -> g x) -> TypeRepMap f -> TypeRepMap g
174hoist :: (forall x. f x -> g x) -> TypeRepMap f -> TypeRepMap g
174−hoist f (TypeRepMap as bs ans) = TypeRepMap as bs $ mapArray' (toAny . f . fromAny) ans
175+hoist f (TypeRepMap as bs ans ks) = TypeRepMap as bs (mapArray' (toAny . f . fromAny) ans) ks
175{-# INLINE hoist #-}
176{-# INLINE hoist #-}
176
177
178+hoistA :: (Applicative t) => (forall x. f x -> t (g x)) -> TypeRepMap f -> t (TypeRepMap g)
179+hoistA f (TypeRepMap as bs (toList -> ans) ks) = (\l -> TypeRepMap as bs (fromList $ map toAny l) ks)
180+ <$> traverse (f . fromAny) ans
181+{-# INLINE hoistA #-}
182+
177-- | The union of two 'TypeRepMap's using a combining function.
183-- | The union of two 'TypeRepMap's using a combining function.
178unionWith :: (forall x. f x -> f x -> f x) -> TypeRepMap f -> TypeRepMap f -> TypeRepMap f
184unionWith :: (forall x. f x -> f x -> f x) -> TypeRepMap f -> TypeRepMap f -> TypeRepMap f
179−unionWith f m1 m2 = fromListPairs
185+unionWith f m1 m2 = fromTriples
180− $ Map.toList
186+ $ toTripleList
181 $ Map.unionWith combine
187 $ Map.unionWith combine
182− (Map.fromList $ toPairList m1)
188+ (fromTripleList $ toTriples m1)
183− (Map.fromList $ toPairList m2)
189+ (fromTripleList $ toTriples m2)
184 where
190 where
185− combine :: Any -> Any -> Any
191+ combine :: (Any, Any) -> (Any, Any) -> (Any, Any)
186− combine a b = toAny $ f (fromAny a) (fromAny b)
192+ combine (av, ak) (bv, _) = (toAny $ f (fromAny av) (fromAny bv), ak)
193+
194+ fromTripleList :: Ord a => [(a, b, c)] -> Map.Map a (b, c)
195+ fromTripleList = Map.fromList . map (\(a, b, c) -> (a, (b, c)))
196+
197+ toTripleList :: Map.Map a (b, c) -> [(a, b, c)]
198+ toTripleList = map (\(a, (b, c)) -> (a, b, c)) . Map.toList
187{-# INLINE unionWith #-}
199{-# INLINE unionWith #-}
188
200
189-- | The (left-biased) union of two 'TypeRepMap's. It prefers the first map when
201-- | The (left-biased) union of two 'TypeRepMap's. It prefers the first map when
@@ -259,56 +271,73 @@ fromAny :: Any -> f a
259fromAny = unsafeCoerce
271fromAny = unsafeCoerce
260
272
261typeFp :: forall a . Typeable a => Fingerprint
273typeFp :: forall a . Typeable a => Fingerprint
262−typeFp = typeRepFingerprint $ typeRep $ Proxy @a
274+typeFp = typeRepFingerprint $ typeRep @a
263{-# INLINE typeFp #-}
275{-# INLINE typeFp #-}
264
276
265−toPairList :: TypeRepMap f -> [(Fingerprint, Any)]
277+toTriples :: TypeRepMap f -> [(Fingerprint, Any, Any)]
266−toPairList tm = zip (toFingerprints tm) (GHC.toList $ anys tm)
278+toTriples tm = zip3 (toFingerprints tm) (GHC.toList $ anys tm) (GHC.toList $ keys tm)
267
279
268−deleteByFst :: Eq a => a -> [(a, b)] -> [(a, b)]
280+deleteByFst :: Eq a => a -> [(a, b, c)] -> [(a, b, c)]
269−deleteByFst x = filter ((/= x) . fst)
281+deleteByFst x = filter ((/= x) . fst3)
270
282
271−nubByFst :: (Eq a) => [(a, b)] -> [(a, b)]
283+nubByFst :: (Eq a) => [(a, b, c)] -> [(a, b, c)]
272−nubByFst = nubBy ((==) `on` fst)
284+nubByFst = nubBy ((==) `on` fst3)
285+
286+fst3 :: (a, b, c) -> a
287+fst3 (a, _, _) = a
273
288
274----------------------------------------------------------------------------
289----------------------------------------------------------------------------
275-- Functions for testing and benchmarking
290-- Functions for testing and benchmarking
276----------------------------------------------------------------------------
291----------------------------------------------------------------------------
277
292
278-- | Existential wrapper around 'Typeable' indexed by @f@ type parameter.
293-- | Existential wrapper around 'Typeable' indexed by @f@ type parameter.
279−-- Useful for 'TypeRepMap' structure creation form list of 'TF's.
294+-- Useful for 'TypeRepMap' structure creation form list of 'WrapTypeable's.
280−data TF f where
295+data WrapTypeable f where
281− TF :: Typeable a => f a -> TF f
296+ WrapTypeable :: Typeable a => f a -> WrapTypeable f
297+
298+instance Show (WrapTypeable f) where
299+ show (WrapTypeable (_ :: f a)) = show $ calcFp @a
282
300
283−instance Show (TF f) where
301+{- |
284− show (TF tf) = show $ calcFp tf
285
302
286−{- | Creates 'TypeRepMap' from a list of 'TF's.
303+prop> fromList . toList == 'id'
287
304
305+Creates 'TypeRepMap' from a list of 'WrapTypeable's.
306+
288−>>> size $ fromList [TF $ Identity True, TF $ Identity 'a']
307+>>> size $ fromList [WrapTypeable $ Identity True, WrapTypeable $ Identity 'a']
2892
3082
290
309
310+
291-}
311-}
292−fromList :: forall f . [TF f] -> TypeRepMap f
312+instance IsList (TypeRepMap f) where
313+ type Item (TypeRepMap f) = WrapTypeable f
314+
315+ fromList :: [WrapTypeable f] -> TypeRepMap f
293−fromList = fromListPairs . map (fp &&& an)
316+ fromList = fromTriples . map (\x -> (fp x, an x, k x))
294− where
317+ where
295− fp :: TF f -> Fingerprint
318+ fp :: WrapTypeable f -> Fingerprint
296− fp (TF x) = calcFp x
319+ fp (WrapTypeable (_ :: f a)) = calcFp @a
320+
321+ an :: WrapTypeable f -> Any
322+ an (WrapTypeable x) = toAny x
297
323
298− an :: TF f -> Any
324+ k :: WrapTypeable f -> Any
299− an (TF x) = toAny x
325+ k (WrapTypeable (_ :: f a)) = unsafeCoerce $ typeRep @a
300
326
301−fromF :: Typeable a => f a -> Proxy a
327+ toList :: TypeRepMap f -> [WrapTypeable f]
302−fromF _ = Proxy
328+ toList = map toWrapTypeable . toTriples
329+ where
330+ toWrapTypeable :: (Fingerprint, Any, Any) -> WrapTypeable f
331+ toWrapTypeable (_, an, k) = withTypeable (unsafeCoerce k) $ fromAny an
303
332
304−calcFp :: Typeable a => f a -> Fingerprint
333+calcFp :: forall a . Typeable a => Fingerprint
305−calcFp = typeRepFingerprint . typeRep . fromF
334+calcFp = typeRepFingerprint $ typeRep @a
306
335
307−fromListPairs :: [(Fingerprint, Any)] -> TypeRepMap f
336+fromTriples :: [(Fingerprint, Any, Any)] -> TypeRepMap f
308−fromListPairs kvs = TypeRepMap (GHC.fromList fpAs) (GHC.fromList fpBs) (GHC.fromList ans)
337+fromTriples kvs = TypeRepMap (GHC.fromList fpAs) (GHC.fromList fpBs) (GHC.fromList ans) (GHC.fromList ks)
309 where
338 where
310 (fpAs, fpBs) = unzip $ map (\(Fingerprint a b) -> (a, b)) fps
339 (fpAs, fpBs) = unzip $ map (\(Fingerprint a b) -> (a, b)) fps
311− (fps, ans) = unzip $ fromSortedList $ sortWith fst $ nubByFst kvs
340+ (fps, ans, ks) = unzip3 $ fromSortedList $ sortWith fst3 $ nubByFst kvs
312
341
313----------------------------------------------------------------------------
342----------------------------------------------------------------------------
314-- Tree-like conversion
343-- Tree-like conversion
test/Test/TypeRep/CacheMap.hs+6−4
@@ -3,19 +3,20 @@ module Test.TypeRep.CacheMap where
3import Prelude hiding (lookup)
3import Prelude hiding (lookup)
4
4
5import Data.Functor.Identity (Identity (..))
5import Data.Functor.Identity (Identity (..))
6+import GHC.Exts (fromList)
6import Test.Tasty.Hspec (Spec, describe, it, shouldBe)
7import Test.Tasty.Hspec (Spec, describe, it, shouldBe)
7
8
8−import Data.TypeRepMap.Internal (TF (..), fromList)
9import Data.TMap (TMap, empty, insert, lookup, one, size, union)
9import Data.TMap (TMap, empty, insert, lookup, one, size, union)
10+import Data.TypeRepMap.Internal (WrapTypeable (..))
10
11
11-- Simple test for 'lookup', 'insert' and 'size' functions.
12-- Simple test for 'lookup', 'insert' and 'size' functions.
12spec_insertLookup :: Spec
13spec_insertLookup :: Spec
13spec_insertLookup = do
14spec_insertLookup = do
14 describe "Lookup Test" $ do
15 describe "Lookup Test" $ do
15 it "returns the inserted element" $
16 it "returns the inserted element" $
16− lookup (fromList [TF $ Identity 'a']) `shouldBe` Just 'a'
17+ lookup (fromList [WrapTypeable $ Identity 'a']) `shouldBe` Just 'a'
17 it "returns the second inserted value of the same type" $
18 it "returns the second inserted value of the same type" $
18− lookup (fromList [TF (Identity 'b'), TF (Identity 'a')]) `shouldBe` Just 'b'
19+ lookup (fromList [WrapTypeable (Identity 'b'), WrapTypeable (Identity 'a')]) `shouldBe` Just 'b'
19
20
20 describe "Size Test" $ do
21 describe "Size Test" $ do
21 it "is empty" $
22 it "is empty" $
@@ -28,7 +29,8 @@ spec_insertLookup = do
28 size mapOf10 `shouldBe` 10
29 size mapOf10 `shouldBe` 10
29
30
30 describe "Union test" $ do
31 describe "Union test" $ do
31− let m = fromList [TF $ Identity 'a', TF $ Identity True] `union` fromList [TF $ Identity 'b']
32+ let m = fromList [WrapTypeable $ Identity 'a', WrapTypeable $ Identity True] `union`
33+ fromList [WrapTypeable $ Identity 'b']
32 it "lookup works on union as expected" $ do
34 it "lookup works on union as expected" $ do
33 lookup m `shouldBe` Just 'a'
35 lookup m `shouldBe` Just 'a'
34 lookup m `shouldBe` Just True
36 lookup m `shouldBe` Just True
test/Test/TypeRep/MapProperty.hs+8−7
@@ -11,13 +11,14 @@ import Prelude hiding (lookup)
11
11
12import Data.Proxy (Proxy (..))
12import Data.Proxy (Proxy (..))
13import Data.Semigroup (Semigroup (..))
13import Data.Semigroup (Semigroup (..))
14+import GHC.Exts (fromList)
14import GHC.Stack (HasCallStack)
15import GHC.Stack (HasCallStack)
15import GHC.TypeLits (Nat, SomeNat (..), someNatVal)
16import GHC.TypeLits (Nat, SomeNat (..), someNatVal)
16import Hedgehog (MonadGen, PropertyT, forAll, property, (===))
17import Hedgehog (MonadGen, PropertyT, forAll, property, (===))
17import Test.Tasty (TestName, TestTree)
18import Test.Tasty (TestName, TestTree)
18import Test.Tasty.Hedgehog (testProperty)
19import Test.Tasty.Hedgehog (testProperty)
19
20
20−import Data.TypeRepMap.Internal (TF (..), TypeRepMap (..), delete, fromList, insert, lookup, member)
21+import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), delete, insert, lookup, member)
21
22
22import qualified Hedgehog.Gen as Gen
23import qualified Hedgehog.Gen as Gen
23import qualified Hedgehog.Range as Range
24import qualified Hedgehog.Range as Range
@@ -38,21 +39,21 @@ prop testName = pure . testProperty testName . property
38test_InsertLookup :: PropertyTest
39test_InsertLookup :: PropertyTest
39test_InsertLookup = prop "lookup k (insert k v m) == Just v" $ do
40test_InsertLookup = prop "lookup k (insert k v m) == Just v" $ do
40 m <- forAll genMap
41 m <- forAll genMap
41− TF (proxy :: IntProxy n) <- forAll genTF
42+ WrapTypeable (proxy :: IntProxy n) <- forAll genTF
42
43
43 lookup @n @IntProxy (insert proxy m) === Just proxy
44 lookup @n @IntProxy (insert proxy m) === Just proxy
44
45
45test_InsertInsert :: PropertyTest
46test_InsertInsert :: PropertyTest
46test_InsertInsert = prop "insert k b . insert k a == insert k b" $ do
47test_InsertInsert = prop "insert k b . insert k a == insert k b" $ do
47 m <- forAll genMap
48 m <- forAll genMap
48− TF a@(IntProxy (proxy :: Proxy n) i) <- forAll genTF
49+ WrapTypeable a@(IntProxy (proxy :: Proxy n) i) <- forAll genTF
49 let b = IntProxy proxy (i + 1)
50 let b = IntProxy proxy (i + 1)
50 lookup @n @IntProxy (insert b $ insert a m) === Just b
51 lookup @n @IntProxy (insert b $ insert a m) === Just b
51
52
52test_DeleteMember :: PropertyTest
53test_DeleteMember :: PropertyTest
53test_DeleteMember = prop "member k . delete k == False" $ do
54test_DeleteMember = prop "member k . delete k == False" $ do
54 m <- forAll genMap
55 m <- forAll genMap
55− TF (proxy :: IntProxy n) <- forAll genTF
56+ WrapTypeable (proxy :: IntProxy n) <- forAll genTF
56 shouldInsert <- forAll Gen.bool
57 shouldInsert <- forAll Gen.bool
57
58
58 if shouldInsert then
59 if shouldInsert then
@@ -72,7 +73,7 @@ newtype FpMap f = FpMap (TypeRepMap f)
72 deriving (Show, Semigroup, Monoid)
73 deriving (Show, Semigroup, Monoid)
73
74
74instance Eq (FpMap f) where
75instance Eq (FpMap f) where
75− FpMap (TypeRepMap as1 bs1 _) == FpMap (TypeRepMap as2 bs2 _) =
76+ FpMap (TypeRepMap as1 bs1 _ _) == FpMap (TypeRepMap as2 bs2 _ _) =
76 as1 == as2 && bs1 == bs2
77 as1 == as2 && bs1 == bs2
77
78
78test_SemigroupAssoc :: PropertyTest
79test_SemigroupAssoc :: PropertyTest
@@ -100,10 +101,10 @@ data IntProxy (n :: Nat) = IntProxy (Proxy n) Int
100genMap :: MonadGen m => m (TypeRepMap IntProxy)
101genMap :: MonadGen m => m (TypeRepMap IntProxy)
101genMap = fromList <$> Gen.list (Range.linear 0 1000) genTF
102genMap = fromList <$> Gen.list (Range.linear 0 1000) genTF
102
103
103−genTF :: MonadGen m => m (TF IntProxy)
104+genTF :: MonadGen m => m (WrapTypeable IntProxy)
104genTF = do
105genTF = do
105 randNat :: Integer <- Gen.integral (Range.linear 0 10000)
106 randNat :: Integer <- Gen.integral (Range.linear 0 10000)
106 randInt <- Gen.int Range.constantBounded
107 randInt <- Gen.int Range.constantBounded
107 case someNatVal randNat of
108 case someNatVal randNat of
108− Just (SomeNat proxyNat) -> pure $ TF $ IntProxy proxyNat randInt
109+ Just (SomeNat proxyNat) -> pure $ WrapTypeable $ IntProxy proxyNat randInt
109 Nothing -> error "Invalid test generator"
110 Nothing -> error "Invalid test generator"
typerep-map.cabal+2−3
@@ -1,5 +1,5 @@
1name: typerep-map
1name: typerep-map
2−version: 0.1.0
2+version: 0.2.0
3synopsis: Efficient implementation of a dependent map with types as keys
3synopsis: Efficient implementation of a dependent map with types as keys
4description:
4description:
5 A dependent map from type representations to values of these types.
5 A dependent map from type representations to values of these types.
@@ -28,8 +28,7 @@ build-type: Simple
28extra-doc-files: README.md
28extra-doc-files: README.md
29 , CHANGELOG.md
29 , CHANGELOG.md
30cabal-version: 2.0
30cabal-version: 2.0
31−tested-with: GHC == 8.0.2
31+tested-with: GHC == 8.2.2
32− , GHC == 8.2.2
33 , GHC == 8.4.3
32 , GHC == 8.4.3
34
33
35source-repository head
34source-repository head