packages feed

typerep-map 0.3.0 → 0.3.1

raw patch · 13 files changed

+260/−114 lines, 13 filesdep +QuickCheckdep ~basedep ~containersdep ~criterionsetup-changed

Dependencies added: QuickCheck

Dependency ranges changed: base, containers, criterion, deepseq, dependent-map, dependent-sum, ghc-prim, ghc-typelits-knownnat, hedgehog, primitive, tasty, tasty-discover, tasty-hedgehog, tasty-hspec, vector

Files

CHANGELOG.md view
@@ -4,6 +4,12 @@ `typerep-map` uses [PVP Versioning][1]. The change log is available [on GitHub][2]. +# 0.3.1++* [#64](https://github.com/kowainik/typerep-map/issues/64):+  Fix segfault in `toList`.+* Support GHC 8.4.4 and 8.6.3.+ # 0.3.0  * [#46](https://github.com/kowainik/typerep-map/issues/46):
README.md view
@@ -7,7 +7,7 @@  `typerep-map` introduces `TMap` and `TypeRepMap` — data structures like [`Map`](http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Map-Lazy.html#t:Map), but where types serve as keys, and values have the types specified in the corresponding key spots. -For the more details on the implementation see [this blog post](https://kowainik.github.io/posts/2018-07-11-typerep-map-step-by-step.html).+For the more details on the implementation see [this blog post](https://kowainik.github.io/posts/2018-07-11-typerep-map-step-by-step).  ## Usage example 
− Setup.hs
@@ -1,2 +0,0 @@-import Distribution.Simple-main = defaultMain
benchmark/CMap.hs view
@@ -9,29 +9,38 @@ {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}  module CMap-       ( benchMap-       , prepareBenchMap+       ( spec        ) where -import Criterion.Main (Benchmark, bench, bgroup, nf)+import Criterion.Main (bench, nf, env, whnf)  import Prelude hiding (lookup) -import Control.DeepSeq (rnf)-import Control.Exception+import Spec import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) import GHC.TypeLits -import Data.TypeRep.CMap (TypeRepMap (..), empty, insert, keys, lookup)+import Data.TypeRep.CMap (TypeRepMap (..), empty, insert, lookup) -benchMap :: Benchmark-benchMap = bgroup "map"-    [ bench "lookup"     $ nf tenLookups bigMap-    --, bench "insert new" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 9999999999)-    --, bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1)-    ]+spec :: BenchSpec+spec = BenchSpec+  { benchLookup = Just $ \name ->+      env (mkMap 10000) $ \ ~bigMap ->+        bench name $ nf tenLookups bigMap+  , benchInsertSmall = Just $ \name -> +      bench name $ whnf (inserts empty 10) (Proxy @ 99999)+  , benchInsertBig = Just $ \name ->+      env (mkMap 10000) $ \ ~(bigMap) ->+       bench name $ whnf (inserts bigMap 1) (Proxy @ 99999)+  , benchUpdateSmall = Just $ \name ->+      env (mkMap 10) $ \ ~(smallMap) ->+      bench name $ whnf (inserts smallMap 10) (Proxy @ 0)+  , benchUpdateBig = Just $ \name ->+      env (mkMap 10000) $ \ ~(bigMap) ->+        bench name $ whnf (inserts bigMap 10) (Proxy @ 0)+  }  tenLookups :: TypeRepMap (Proxy :: Nat -> *)            -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40@@ -42,16 +51,20 @@     lp :: forall (a::Nat). Typeable a => Proxy a     lp = fromJust $ lookup tmap --- TypeRepMap of 10000 elements-bigMap :: TypeRepMap (Proxy :: Nat -> *)-bigMap = buildBigMap 10000 (Proxy :: Proxy 0) empty+inserts :: forall a . (KnownNat a)+        => TypeRepMap (Proxy :: Nat -> *)+        -> Int+        -> Proxy (a :: Nat)+        -> TypeRepMap (Proxy :: Nat -> *)+inserts !c 0 _ = c+inserts !c n x = inserts+   (insert x c)+   (n-1)+   (Proxy :: Proxy (a+1)) +mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> *))+mkMap n = pure $ buildBigMap n (Proxy :: Proxy 0) empty+ buildBigMap :: forall a . (KnownNat a) => Int -> Proxy (a :: Nat) -> TypeRepMap (Proxy :: Nat -> *) -> TypeRepMap (Proxy :: Nat -> *) buildBigMap 1 x = insert x buildBigMap n x = insert x . buildBigMap (n - 1) (Proxy :: Proxy (a + 1))--rknf :: TypeRepMap f -> ()-rknf = rnf . keys--prepareBenchMap :: IO ()-prepareBenchMap = evaluate (rknf bigMap)
benchmark/CacheMap.hs view
@@ -9,10 +9,11 @@ {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}  module CacheMap-       ( benchCacheMap+       ( spec        ) where -import Criterion.Main (Benchmark, bench, bgroup, nf)+import Criterion.Main (bench, nf, whnf, env)+import Spec  import Prelude hiding (lookup) @@ -22,14 +23,25 @@ import GHC.Exts (fromList) import GHC.TypeLits -import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), lookup)+import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), lookup, insert, empty) -benchCacheMap :: Benchmark-benchCacheMap = bgroup "vector optimal cache"-   [ bench "lookup" $ nf tenLookups bigMap-   -- , bench "insert new" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 9999999999)-   -- , bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1)-   ]+spec :: BenchSpec+spec = BenchSpec+  { benchLookup = Just $ \name ->+      env (mkMap 10000) $ \ ~bigMap ->+        bench name $ nf tenLookups bigMap+  , benchInsertSmall = Just $ \name -> +      bench name $ whnf (inserts empty 10) (Proxy @ 99999)+  , benchInsertBig = Just $ \name ->+      env (mkMap 10000) $ \ ~(bigMap) ->+       bench name $ whnf (inserts bigMap 1) (Proxy @ 99999)+  , benchUpdateSmall = Just $ \name ->+      env (mkMap 10) $ \ ~(smallMap) ->+      bench name $ whnf (inserts smallMap 10) (Proxy @ 0)+  , benchUpdateBig = Just $ \name ->+      env (mkMap 10000) $ \ ~(bigMap) ->+        bench name $ whnf (inserts bigMap 10) (Proxy @ 0)+  }  tenLookups :: TypeRepMap (Proxy :: Nat -> *)            -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40@@ -40,9 +52,20 @@     lp :: forall (a::Nat). Typeable a => Proxy a     lp = fromJust $ lookup tmap --- TypeRepMap of 10000 elements-bigMap :: TypeRepMap (Proxy :: Nat -> *)-bigMap = fromList $ buildBigMap 10000 (Proxy :: Proxy 0) []+inserts :: forall a . (KnownNat a)+        => TypeRepMap (Proxy :: Nat -> *)+        -> Int+        -> Proxy (a :: Nat)+        -> TypeRepMap (Proxy :: Nat -> *)+inserts !c 0 _ = c+inserts !c n x = inserts+   (insert x c)+   (n-1)+   (Proxy :: Proxy (a+1))++mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> *))+mkMap n = pure $ fromList $ buildBigMap n (Proxy :: Proxy 0) []+  buildBigMap :: forall a . (KnownNat a)             => Int
benchmark/DMap.hs view
@@ -11,16 +11,15 @@ {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver -fno-warn-orphans #-}  module DMap-       ( benchDMap-       , prepareBenchDMap+       ( spec        ) where -import Criterion.Main (Benchmark, bench, bgroup, nf)+import Criterion.Main (bench, nf, whnf, env)  import Prelude hiding (lookup) -import Control.DeepSeq (rnf)-import Control.Exception+import Spec+import Control.DeepSeq (NFData(..)) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Type.Equality ((:~:) (..))@@ -35,13 +34,21 @@  type TypeRepMap = DMap TypeRep -benchDMap :: Benchmark-benchDMap = bgroup "dependent map"-   [ bench "lookup"     $ nf tenLookups bigMap-   -- , bench "insert new" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 9999999999)-   -- , bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1)-   ] +spec :: BenchSpec+spec = BenchSpec+  { benchLookup = Just $ \name ->+      env mkBigMap $ \ ~(DMapNF bigMap) ->+        bench name $ nf tenLookups bigMap+  , benchInsertSmall = Just $ \name -> +      bench name $ whnf (inserts empty 10) (Proxy @ 99999)+  , benchInsertBig = Just $ \name ->+      env mkBigMap $ \ ~(DMapNF bigMap) ->+       bench name $ whnf (inserts bigMap 1) (Proxy @ 99999)+  , benchUpdateSmall = Nothing -- Not implemented+  , benchUpdateBig = Nothing -- Not implemented+  }+ tenLookups :: TypeRepMap (Proxy :: Nat -> *)            -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40               , Proxy 50, Proxy 60, Proxy 70, Proxy 80@@ -51,9 +58,20 @@     lp :: forall (a :: Nat) . Typeable a => Proxy a     lp = fromJust $ lookup (typeRep @a) tmap +inserts :: forall a . (KnownNat a)+        => TypeRepMap (Proxy :: Nat -> *)+        -> Int+        -> Proxy (a :: Nat)+        -> TypeRepMap (Proxy :: Nat -> *)+inserts !c 0 _ = c+inserts !c n x = inserts+   (insert (typeRep @ a) x c)+   (n-1)+   (Proxy :: Proxy (a+1))+ -- TypeRepMap of 10000 elements-bigMap :: TypeRepMap (Proxy :: Nat -> *)-bigMap = buildBigMap 10000 (Proxy :: Proxy 0) empty+mkBigMap :: IO (DMapNF (Proxy :: Nat -> *))+mkBigMap = pure . DMapNF $ buildBigMap 10000 (Proxy :: Proxy 0) empty  buildBigMap :: forall a . (KnownNat a)             => Int@@ -64,11 +82,12 @@ buildBigMap n x = insert (typeRep @a) x                 . buildBigMap (n - 1) (Proxy @(a + 1)) -rknf :: TypeRepMap f -> ()-rknf = rnf . map (\(This t) -> typeRepFingerprint t) . keys+-- | Wrapper that provides NFData instance to the 'DMap' structure.+newtype DMapNF f = DMapNF (TypeRepMap f) -prepareBenchDMap :: IO ()-prepareBenchDMap = evaluate (rknf bigMap)+instance NFData (DMapNF f) where+  rnf (DMapNF x) = +    rnf . map (\(This t) -> typeRepFingerprint t) $ keys x  instance GEq TypeRep where     geq :: TypeRep a -> TypeRep b -> Maybe (a :~: b)
benchmark/Main.hs view
@@ -2,30 +2,46 @@  module Main where -import Criterion.Main (defaultMain)+import Criterion.Main (defaultMain, bgroup) -import CacheMap (benchCacheMap)-import CMap (benchMap, prepareBenchMap)+import Spec+import qualified CMap+import qualified CacheMap #if ( __GLASGOW_HASKELL__ >= 802 )-import DMap (benchDMap, prepareBenchDMap)+import qualified DMap #endif-import OptimalVector (benchVectorOpt, prepareBenchVectorOpt)---import Vector (benchVector, prepareBenchVector)+import qualified OptimalVector as OptVec  main :: IO () main = do-  prepareBenchMap-  --prepareBenchVector-  prepareBenchVectorOpt+  let specs = [("CMap", CMap.spec)+              ,("CacheMap", CacheMap.spec) #if ( __GLASGOW_HASKELL__ >= 802 )-  prepareBenchDMap+              , ("DMap", DMap.spec) #endif+              , ("OptVec", OptVec.spec)+              ]+      -- This code creates a benchmark group. Given a getter+      -- (that is test description) it gets a benchmark generation+      -- function from each module spec. Benchmark generation+      -- function takes a label and generate benchmarks. It's+      -- possible to introduce parameters passing in the same way.+      mkGroup getBenchmark = +        [ mkBenchmark label+        | (label, spec) <- specs+          -- Here we use pure to force pattern matching in List+          -- then in case of pattern match failure `mzero` will+          -- be called, so benchmark will be ignored.+        , Just mkBenchmark <- pure $ getBenchmark spec+        ]   defaultMain-    [ benchMap-   -- , benchVector-    , benchCacheMap-    , benchVectorOpt-#if ( __GLASGOW_HASKELL__ >= 802 )-    , benchDMap-#endif-    ]+    [ bgroup "lookup" $ mkGroup benchLookup +    , bgroup "insert"+       [ bgroup "10 elements to empty" $ mkGroup benchInsertSmall+       , bgroup "1 element to big map" $ mkGroup benchInsertBig+       ]+    , bgroup "update"+       [ bgroup "10 elements to empty" $ mkGroup benchUpdateSmall+       , bgroup "1 element to big map" $ mkGroup benchUpdateBig+       ]+    ] 
benchmark/OptimalVector.hs view
@@ -10,16 +10,14 @@ {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}  module OptimalVector-       ( benchVectorOpt-       , prepareBenchVectorOpt+       ( spec        ) where -import Criterion.Main (Benchmark, bench, bgroup, nf)+import Spec+import Criterion.Main (bench, nf, env)  import Prelude hiding (lookup) -import Control.DeepSeq (rnf)-import Control.Exception import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable)@@ -27,13 +25,17 @@  import Data.TypeRep.OptimalVector (TF (..), TypeRepMap (..), fromList, lookup) -benchVectorOpt :: Benchmark-benchVectorOpt = bgroup "vector optimal"-   [ bench "lookup"     $ nf tenLookups bigMap-   -- , bench "insert new" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 9999999999)-   -- , bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1)-   ]-+spec :: BenchSpec+spec = BenchSpec+  { benchLookup = Just $ \name ->+      env mkBigMap $ \ ~bigMap ->+        bench name $ nf tenLookups bigMap+  , benchInsertSmall = Nothing -- Not implemented+  , benchInsertBig = Nothing -- Not implemented+  , benchUpdateSmall = Nothing -- Not implemented+  , benchUpdateBig = Nothing -- Not implemented+  }+   tenLookups :: TypeRepMap (Proxy :: Nat -> *)            -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40               , Proxy 50, Proxy 60, Proxy 70, Proxy 80@@ -44,8 +46,8 @@     lp = fromJust $ lookup tmap  -- TypeRepMap of 10000 elements-bigMap :: TypeRepMap (Proxy :: Nat -> *)-bigMap = fromList $ buildBigMap 10000 (Proxy :: Proxy 0) []+mkBigMap :: IO (TypeRepMap (Proxy :: Nat -> *))+mkBigMap = pure $ fromList $ buildBigMap 10000 (Proxy :: Proxy 0) []  buildBigMap :: forall a . (KnownNat a)             => Int@@ -55,8 +57,3 @@ buildBigMap 1 x = (TF x :) buildBigMap n x = (TF x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1)) -rknf :: TypeRepMap f -> ()-rknf tVect = rnf (fingerprintAs tVect, fingerprintBs tVect)--prepareBenchVectorOpt :: IO ()-prepareBenchVectorOpt = evaluate (rknf bigMap)
+ benchmark/Spec.hs view
@@ -0,0 +1,53 @@+-- | Specification of the benchmarks.+-- This module keeps a list of all bencharks, this way+-- we can group benchmark by the interesting function, not+-- by the implementation.+module Spec+  ( BenchSpec(..)+  ) where++import Criterion++-- | List of benchmarks that each module should provide.+-- If implementation can express the benchmark then it+-- can return @Nothing@ in that benchmark.+--+-- Map should contain elements from @1@ to @size of map@+-- inserted in ascending order (later that requirement may+-- change).+data BenchSpec = BenchSpec+  { benchLookup :: Maybe (String -> Benchmark)+    -- ^ Basic lookup we look 10 values inside 10k map.+    --+    -- Implementation may look like:+    -- @+    -- tenLookups :: TypeRepMap (Proxy :: Nat -> *)+    --            -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40+    --               , Proxy 50, Proxy 60, Proxy 70, Proxy 80+    --               )+    -- tenLookups tmap = (lp, lp, lp, lp, lp, lp, lp, lp)+    -- @+  , benchInsertSmall :: Maybe (String -> Benchmark)+    -- ^ Insert 10 elements into an empty map.+    --+    -- Implementation may look like:+    -- @+    -- inserts :: forall a . (KnownNat a)+    --         => TypeRepMap (Proxy :: Nat -> *)+    --         -> Int+    --         -> Proxy (a :: Nat)+    --         -> TypeRepMap (Proxy :: Nat -> *)+    -- inserts !c 0 _ = c+    -- inserts !c n x = inserts (insert x c) (n-1) (Proxy :: Proxy (a+1))+    -- @+  , benchInsertBig :: Maybe (String -> Benchmark)+    -- ^ Insert 10 elements into a big map. Implementation is like+    -- a small map, but should insert values into 10k elements map.+  , benchUpdateSmall :: Maybe (String -> Benchmark)+    -- ^ Insert 10 elements into map of 10 elements, where each key+    -- was already inserted in the map+  , benchUpdateBig ::  Maybe (String -> Benchmark)+    -- ^ Insert 10 elements into map of 10k elements, where each key+    -- was already inserted in the map+  }+
src/Data/TypeRepMap/Internal.hs view
@@ -25,6 +25,7 @@  import Control.Monad.ST (ST, runST) import Control.Monad.Zip (mzip)+import Control.DeepSeq import Data.Function (on) import Data.Kind (Type) import Data.List (intercalate, nubBy)@@ -74,6 +75,9 @@     }   -- ^ an unsafe constructor for 'TypeRepMap' +instance NFData (TypeRepMap f) where+   rnf x = rnf (keys x) `seq` ()+ -- | Shows only keys. instance Show (TypeRepMap f) where     show TypeRepMap{..} = "TypeRepMap [" ++ showKeys ++ "]"@@ -341,6 +345,9 @@ instance Show (WrapTypeable f) where     show (WrapTypeable (_ :: f a)) = show $ calcFp @a +wrapTypeable :: TypeRep a -> f a -> WrapTypeable f+wrapTypeable tr = withTypeable tr WrapTypeable+ {- |  prop> fromList . toList == 'id'@@ -371,7 +378,7 @@     toList = map toWrapTypeable . toTriples       where         toWrapTypeable :: (Fingerprint, Any, Any) -> WrapTypeable f-        toWrapTypeable (_, an, k) = withTypeable (unsafeCoerce k) $ fromAny an+        toWrapTypeable (_, an, k) = wrapTypeable (unsafeCoerce k) (fromAny an)  calcFp :: forall a . Typeable a => Fingerprint calcFp = typeRepFingerprint $ typeRep @a
typerep-extra-impls/Data/TypeRep/CMap.hs view
@@ -12,6 +12,7 @@  import Prelude hiding (lookup) +import Control.DeepSeq import Data.Proxy (Proxy (..)) import Data.Typeable (TypeRep, Typeable, typeRep) import GHC.Base (Any)@@ -23,6 +24,9 @@ newtype TypeRepMap (f :: k -> *) = TypeRepMap     { unMap :: LMap.Map TypeRep Any     }++instance NFData (TypeRepMap f) where+  rnf x = rnf (keys x) `seq` ()  -- | Empty structure. empty :: TypeRepMap f
typerep-extra-impls/Data/TypeRep/OptimalVector.hs view
@@ -23,6 +23,7 @@ import Prelude hiding (lookup)  import Control.Arrow ((&&&))+import Control.DeepSeq import Data.Kind (Type) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable, typeRep, typeRepFingerprint)@@ -40,6 +41,9 @@     , fingerprintBs :: Unboxed.Vector Word64     , anys          :: V.Vector Any     }++instance NFData (TypeRepMap f) where+  rnf x = x `seq` ()  fromAny :: Any -> f a fromAny = unsafeCoerce
typerep-map.cabal view
@@ -1,5 +1,5 @@ name:                typerep-map-version:             0.3.0+version:             0.3.1 synopsis:            Efficient implementation of a dependent map with types as keys description:     A dependent map from type representations to values of these types.@@ -22,14 +22,15 @@ license-file:        LICENSE author:              Kowainik, Vladislav Zavialov maintainer:          xrom.xkov@gmail.com-copyright:           2017-2018 Kowainik+copyright:           2017-present Kowainik category:            Data, Data Structures, Types build-type:          Simple extra-doc-files:     README.md                    , CHANGELOG.md cabal-version:       2.0 tested-with:         GHC == 8.2.2-                   , GHC == 8.4.3+                   , GHC == 8.4.4+                   , GHC == 8.6.3  source-repository head   type:                git@@ -41,10 +42,11 @@                        Data.TypeRepMap                        Data.TypeRepMap.Internal   ghc-options:         -Wall-  build-depends:       base >= 4.9 && < 5-                     , containers-                     , ghc-prim-                     , primitive >= 0.6.4+  build-depends:       base >= 4.10 && < 5+                     , containers >= 0.5.10.2 && < 0.7+                     , ghc-prim ^>= 0.5.1.1+                     , primitive ^>= 0.6.4+                     , deepseq ^>= 1.4   default-extensions:  OverloadedStrings                        RecordWildCards                        ScopedTypeVariables@@ -57,9 +59,10 @@                        Data.TypeRep.OptimalVector                        Data.TypeRep.Vector   ghc-options:         -Wall-  build-depends:       base-                     , containers-                     , vector+  build-depends:       base >= 4.10 && < 5+                     , containers >= 0.5.10.2 && < 0.7+                     , vector ^>= 0.12.0.1+                     , deepseq ^>= 1.4   default-extensions:  OverloadedStrings                        RecordWildCards                        ScopedTypeVariables@@ -76,15 +79,16 @@                      , Test.TypeRep.MapProperty                      , Test.TypeRep.Vector                      , Test.TypeRep.VectorOpt-  build-depends:       base-                     , ghc-typelits-knownnat-                     , hedgehog+  build-depends:       base >= 4.10 && < 5+                     , ghc-typelits-knownnat >= 0.4.2 && < 0.7+                     , hedgehog >= 0.5.3 && < 0.7                      , typerep-map                      , typerep-extra-impls-                     , tasty-                     , tasty-discover >= 4.1.1-                     , tasty-hedgehog-                     , tasty-hspec+                     , tasty >= 1.0.1.1 && < 1.3+                     , tasty-discover >= 4.1.1 && < 4.3+                     , tasty-hedgehog >= 0.1.0.2 && < 0.3+                     , tasty-hspec ^>= 1.1.5+                     , QuickCheck >= 2.11.3 && < 2.13   build-tool-depends:  tasty-discover:tasty-discover   ghc-options:         -Wall -threaded -rtsopts -with-rtsopts=-N   default-extensions:  ScopedTypeVariables@@ -100,19 +104,21 @@   main-is:             Main.hs   other-modules:       CMap                      , CacheMap+                     , Spec                      , Vector                      , OptimalVector-  build-depends:       base-                     , criterion-                     , deepseq-                     , dependent-map-                     , dependent-sum-                     , ghc-typelits-knownnat+  build-depends:       base >= 4.10 && < 5+                     , criterion >= 1.4.1.0 && < 1.6+                     , deepseq ^>= 1.4.3.0+                     , dependent-map >= 0.2.4.0 && < 0.5+                     , dependent-sum ^>= 0.4+                     , ghc-typelits-knownnat >= 0.4.2 && < 0.7                      , typerep-map                      , typerep-extra-impls   default-extensions:  OverloadedStrings                        RecordWildCards                        ScopedTypeVariables                        TypeApplications+                       BangPatterns   if impl(ghc >= 8.2.2)     other-modules:     DMap