diff --git a/benchmark/CMap.hs b/benchmark/CMap.hs index 2a8cf63..d25502f 100644 --- a/benchmark/CMap.hs +++ b/benchmark/CMap.hs @@ -1,70 +1,77 @@ +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ExplicitNamespaces #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} - module CMap - ( spec - ) where - -import Criterion.Main (bench, nf, env, whnf) + ( spec + ) where import Prelude hiding (lookup) -import Spec +import Criterion.Main (bench, env, nf, whnf) +import Data.Kind (Type) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) -import GHC.TypeLits +import GHC.TypeLits (type (+), KnownNat, Nat) import Data.TypeRep.CMap (TypeRepMap (..), empty, insert, lookup) +import Spec (BenchSpec (..)) + + 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) - } + { 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 - , Proxy 50, Proxy 60, Proxy 70, Proxy 80 - ) +tenLookups + :: TypeRepMap (Proxy :: Nat -> Type) + -> ( 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) where lp :: forall (a::Nat). Typeable a => Proxy a lp = fromJust $ lookup tmap -inserts :: forall a . (KnownNat a) - => TypeRepMap (Proxy :: Nat -> *) - -> Int - -> Proxy (a :: Nat) - -> TypeRepMap (Proxy :: Nat -> *) +inserts + :: forall a . (KnownNat a) + => TypeRepMap (Proxy :: Nat -> Type) + -> Int + -> Proxy (a :: Nat) + -> TypeRepMap (Proxy :: Nat -> Type) inserts !c 0 _ = c inserts !c n x = inserts - (insert x c) - (n-1) - (Proxy :: Proxy (a+1)) + (insert x c) + (n-1) + (Proxy :: Proxy (a+1)) -mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> *)) +mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> Type)) 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 + :: forall a . (KnownNat a) + => Int + -> Proxy (a :: Nat) + -> TypeRepMap (Proxy :: Nat -> Type) + -> TypeRepMap (Proxy :: Nat -> Type) buildBigMap 1 x = insert x buildBigMap n x = insert x . buildBigMap (n - 1) (Proxy :: Proxy (a + 1)) diff --git a/benchmark/CacheMap.hs b/benchmark/CacheMap.hs index 5dedb74..395585c 100644 --- a/benchmark/CacheMap.hs +++ b/benchmark/CacheMap.hs @@ -1,76 +1,79 @@ +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ExplicitNamespaces #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} - module CacheMap - ( spec - ) where - -import Criterion.Main (bench, nf, whnf, env) -import Spec + ( spec + ) where import Prelude hiding (lookup) +import Criterion.Main (bench, env, nf, whnf) +import Data.Kind (Type) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) import GHC.Exts (fromList) -import GHC.TypeLits +import GHC.TypeLits (type (+), KnownNat, Nat) + +import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), empty, insert, lookup) + +import Spec (BenchSpec (..)) -import Data.TypeRepMap.Internal (TypeRepMap (..), WrapTypeable (..), lookup, insert, empty) 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) - } + { 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 - , Proxy 50, Proxy 60, Proxy 70, Proxy 80 - ) +tenLookups + :: TypeRepMap (Proxy :: Nat -> Type) + -> ( 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) where - lp :: forall (a::Nat). Typeable a => Proxy a + lp :: forall (a :: Nat) . Typeable a => Proxy a lp = fromJust $ lookup tmap -inserts :: forall a . (KnownNat a) - => TypeRepMap (Proxy :: Nat -> *) - -> Int - -> Proxy (a :: Nat) - -> TypeRepMap (Proxy :: Nat -> *) +inserts + :: forall a . (KnownNat a) + => TypeRepMap (Proxy :: Nat -> Type) + -> Int + -> Proxy (a :: Nat) + -> TypeRepMap (Proxy :: Nat -> Type) inserts !c 0 _ = c inserts !c n x = inserts - (insert x c) - (n-1) - (Proxy :: Proxy (a+1)) + (insert x c) + (n-1) + (Proxy :: Proxy (a + 1)) -mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> *)) +mkMap :: Int -> IO (TypeRepMap (Proxy :: Nat -> Type)) mkMap n = pure $ fromList $ buildBigMap n (Proxy :: Proxy 0) [] -buildBigMap :: forall a . (KnownNat a) - => Int - -> Proxy (a :: Nat) - -> [WrapTypeable (Proxy :: Nat -> *)] - -> [WrapTypeable (Proxy :: Nat -> *)] +buildBigMap + :: forall a . (KnownNat a) + => Int + -> Proxy (a :: Nat) + -> [WrapTypeable (Proxy :: Nat -> Type)] + -> [WrapTypeable (Proxy :: Nat -> Type)] buildBigMap 1 x = (WrapTypeable x :) buildBigMap n x = (WrapTypeable x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1)) diff --git a/benchmark/DMap.hs b/benchmark/DMap.hs index 526765b..5d5b6b2 100644 --- a/benchmark/DMap.hs +++ b/benchmark/DMap.hs @@ -1,79 +1,81 @@ +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ExplicitNamespaces #-} {-# LANGUAGE InstanceSigs #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} - module DMap - ( spec - ) where - -import Criterion.Main (bench, env, nf, whnf) + ( spec + ) where import Prelude hiding (lookup) import Control.DeepSeq (NFData (..)) +import Criterion.Main (bench, env, nf, whnf) +import Data.Kind (Type) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) -import GHC.TypeLits -import Spec +import GHC.TypeLits (type (+), KnownNat, Nat) import Type.Reflection (TypeRep, Typeable, typeRep) import Type.Reflection.Unsafe (typeRepFingerprint) import Data.Dependent.Map (DMap, empty, insert, keys, lookup) import Data.Some (Some (Some)) -type TypeRepMap = DMap TypeRep +import Spec (BenchSpec (..)) +type TypeRepMap = DMap TypeRep + 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 - } + { 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 - ) +tenLookups + :: TypeRepMap (Proxy :: Nat -> Type) + -> ( 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) where 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 + :: forall a . (KnownNat a) + => TypeRepMap (Proxy :: Nat -> Type) + -> Int + -> Proxy (a :: Nat) + -> TypeRepMap (Proxy :: Nat -> Type) inserts !c 0 _ = c inserts !c n x = inserts - (insert (typeRep @ a) x c) - (n-1) - (Proxy :: Proxy (a+1)) + (insert (typeRep @ a) x c) + (n-1) + (Proxy :: Proxy (a+1)) -- TypeRepMap of 10000 elements -mkBigMap :: IO (DMapNF (Proxy :: Nat -> *)) +mkBigMap :: IO (DMapNF (Proxy :: Nat -> Type)) mkBigMap = pure . DMapNF $ buildBigMap 10000 (Proxy :: Proxy 0) empty -buildBigMap :: forall a . (KnownNat a) - => Int - -> Proxy (a :: Nat) - -> TypeRepMap (Proxy :: Nat -> *) - -> TypeRepMap (Proxy :: Nat -> *) +buildBigMap + :: forall a . (KnownNat a) + => Int + -> Proxy (a :: Nat) + -> TypeRepMap (Proxy :: Nat -> Type) + -> TypeRepMap (Proxy :: Nat -> Type) buildBigMap 1 x = insert (typeRep @a) x buildBigMap n x = insert (typeRep @a) x . buildBigMap (n - 1) (Proxy @(a + 1)) @@ -82,5 +84,6 @@ buildBigMap n x = insert (typeRep @a) x newtype DMapNF f = DMapNF (TypeRepMap f) instance NFData (DMapNF f) where - rnf (DMapNF x) = - rnf . map (\(Some t) -> typeRepFingerprint t) $ keys x + rnf :: DMapNF f -> () + rnf (DMapNF x) = + rnf . map (\(Some t) -> typeRepFingerprint t) $ keys x diff --git a/benchmark/Main.hs b/benchmark/Main.hs index eded89f..3303b2d 100644 --- a/benchmark/Main.hs +++ b/benchmark/Main.hs @@ -1,47 +1,52 @@ {-# LANGUAGE CPP #-} -module Main where +module Main + ( main + ) where -import Criterion.Main (defaultMain, bgroup) +import Criterion.Main (bgroup, defaultMain) + +import Spec (BenchSpec (..)) -import Spec -import qualified CMap import qualified CacheMap +import qualified CMap #if ( __GLASGOW_HASKELL__ >= 802 ) import qualified DMap #endif import qualified OptimalVector as OptVec + main :: IO () main = do - let specs = [("CMap", CMap.spec) - ,("CacheMap", CacheMap.spec) + let specs = [("CMap", CMap.spec) + ,("CacheMap", CacheMap.spec) #if ( __GLASGOW_HASKELL__ >= 802 ) - , ("DMap", DMap.spec) + , ("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 + , ("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. + --} + let 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 + [ 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 + ] ] - defaultMain - [ 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 - ] - ] diff --git a/benchmark/OptimalVector.hs b/benchmark/OptimalVector.hs index 5d5a17c..3149447 100644 --- a/benchmark/OptimalVector.hs +++ b/benchmark/OptimalVector.hs @@ -1,59 +1,60 @@ +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ExplicitNamespaces #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} - module OptimalVector ( spec ) where -import Spec -import Criterion.Main (bench, nf, env) - import Prelude hiding (lookup) +import Criterion.Main (bench, env, nf) +import Data.Kind (Type) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) -import GHC.TypeLits +import GHC.TypeLits (type (+), KnownNat, Nat) import Data.TypeRep.OptimalVector (TF (..), TypeRepMap (..), fromList, lookup) +import Spec (BenchSpec (..)) + + 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 - ) + { 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 -> Type) + -> ( 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) where lp :: forall (a::Nat). Typeable a => Proxy a lp = fromJust $ lookup tmap -- TypeRepMap of 10000 elements -mkBigMap :: IO (TypeRepMap (Proxy :: Nat -> *)) +mkBigMap :: IO (TypeRepMap (Proxy :: Nat -> Type)) mkBigMap = pure $ fromList $ buildBigMap 10000 (Proxy :: Proxy 0) [] -buildBigMap :: forall a . (KnownNat a) - => Int - -> Proxy (a :: Nat) - -> [TF (Proxy :: Nat -> *)] - -> [TF (Proxy :: Nat -> *)] +buildBigMap + :: forall a . (KnownNat a) + => Int + -> Proxy (a :: Nat) + -> [TF (Proxy :: Nat -> Type)] + -> [TF (Proxy :: Nat -> Type)] buildBigMap 1 x = (TF x :) buildBigMap n x = (TF x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1)) - diff --git a/benchmark/Spec.hs b/benchmark/Spec.hs index abcb2ea..d780266 100644 --- a/benchmark/Spec.hs +++ b/benchmark/Spec.hs @@ -1,53 +1,64 @@ --- | 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. +{- | 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). + ( BenchSpec(..) + ) where + +import Criterion (Benchmark) + + +{- | 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 - } + { {- | 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) + @ + -} + benchLookup :: 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)) + @ + -} + , benchInsertSmall :: Maybe (String -> Benchmark) + {- ^ Insert 10 elements into a big map. Implementation is like + a small map, but should insert values into 10k elements map. + -} + , benchInsertBig :: Maybe (String -> Benchmark) + {- ^ Insert 10 elements into map of 10 elements, where each key + was already inserted in the map + -} + , benchUpdateSmall :: Maybe (String -> Benchmark) + {- ^ Insert 10 elements into map of 10k elements, where each key + was already inserted in the map + -} + , benchUpdateBig :: Maybe (String -> Benchmark) + } diff --git a/benchmark/Vector.hs b/benchmark/Vector.hs index 20334cd..8763c04 100644 --- a/benchmark/Vector.hs +++ b/benchmark/Vector.hs @@ -1,31 +1,30 @@ +{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} + {-# LANGUAGE DataKinds #-} -{-# LANGUAGE ExplicitNamespaces #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} - module Vector - ( benchVector - , prepareBenchVector - ) where - -import Criterion.Main (Benchmark, bench, bgroup, nf) + ( benchVector + , prepareBenchVector + ) where import Prelude hiding (lookup) import Control.DeepSeq (rnf) -import Control.Exception +import Control.Exception (evaluate) +import Criterion.Main (Benchmark, bench, bgroup, nf) +import Data.Kind (Type) import Data.Maybe (fromJust) import Data.Proxy (Proxy (..)) import Data.Typeable (Typeable) -import GHC.TypeLits +import GHC.TypeLits (type (+), KnownNat, Nat) + +import Data.TypeRep.Vector (TF (..), TypeRepVector, fingerprints, fromList, lookup) -import Data.TypeRep.Vector benchVector :: Benchmark benchVector = bgroup "vector" @@ -34,24 +33,26 @@ benchVector = bgroup "vector" -- , bench "update old" $ whnf (\x -> rknf $ insert x bigMap) (Proxy :: Proxy 1) ] -tenLookups :: TypeRepVector (Proxy :: Nat -> *) - -> ( Proxy 10, Proxy 20, Proxy 30, Proxy 40 - , Proxy 50, Proxy 60, Proxy 70, Proxy 80 - ) +tenLookups + :: TypeRepVector (Proxy :: Nat -> Type) + -> ( 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) where lp :: forall (a::Nat). Typeable a => Proxy a lp = fromJust $ lookup tmap -- TypeRepMap of 10000 elements -bigMap :: TypeRepVector (Proxy :: Nat -> *) +bigMap :: TypeRepVector (Proxy :: Nat -> Type) bigMap = fromList $ buildBigMap 10000 (Proxy :: Proxy 0) [] -buildBigMap :: forall a . (KnownNat a) - => Int - -> Proxy (a :: Nat) - -> [TF (Proxy :: Nat -> *)] - -> [TF (Proxy :: Nat -> *)] +buildBigMap + :: forall a . (KnownNat a) + => Int + -> Proxy (a :: Nat) + -> [TF (Proxy :: Nat -> Type)] + -> [TF (Proxy :: Nat -> Type)] buildBigMap 1 x = (TF x :) buildBigMap n x = (TF x :) . buildBigMap (n - 1) (Proxy :: Proxy (a + 1)) diff --git a/src/Data/TMap.hs b/src/Data/TMap.hs index 01fce26..7714d74 100644 --- a/src/Data/TMap.hs +++ b/src/Data/TMap.hs @@ -170,5 +170,5 @@ adjust :: Typeable a => (a -> a) -> TMap -> TMap adjust f = F.adjust (liftToIdentity f) {-# INLINE adjust #-} -liftToIdentity :: forall a. Typeable a => (a -> a) -> Identity a -> Identity a +liftToIdentity :: forall a. (a -> a) -> Identity a -> Identity a liftToIdentity = coerce diff --git a/src/Data/TypeRepMap/Internal.hs b/src/Data/TypeRepMap/Internal.hs index 1170acb..6e58b75 100644 --- a/src/Data/TypeRepMap/Internal.hs +++ b/src/Data/TypeRepMap/Internal.hs @@ -1,10 +1,11 @@ +{-# OPTIONS_GHC -Wno-missing-export-lists #-} + {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE InstanceSigs #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE Rank2Types #-} diff --git a/test/Test/TypeRep/TypeRepMapProperty.hs b/test/Test/TypeRep/TypeRepMapProperty.hs index f136df9..6e4810d 100644 --- a/test/Test/TypeRep/TypeRepMapProperty.hs +++ b/test/Test/TypeRep/TypeRepMapProperty.hs @@ -1,7 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-} @@ -15,9 +14,8 @@ import Prelude hiding (lookup) import Data.Proxy (Proxy (..)) import Data.Semigroup (Semigroup (..)) import GHC.Exts (fromList) -import GHC.Stack (HasCallStack) import GHC.TypeLits (Nat, SomeNat (..), someNatVal) -import Hedgehog (MonadGen, PropertyT, assert, forAll, property, (===)) +import Hedgehog (MonadGen, assert, forAll, (===)) import Test.Hspec (Arg, Expectation, Spec, SpecWith, describe, it) import Test.Hspec.Hedgehog (hedgehog) diff --git a/typerep-extra-impls/Data/TypeRep/CMap.hs b/typerep-extra-impls/Data/TypeRep/CMap.hs index 41dd4f4..8f38e03 100644 --- a/typerep-extra-impls/Data/TypeRep/CMap.hs +++ b/typerep-extra-impls/Data/TypeRep/CMap.hs @@ -1,5 +1,4 @@ -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE PolyKinds #-} {- | Copyright: (c) 2017-2020 Kowainik @@ -21,6 +20,7 @@ module Data.TypeRep.CMap import Prelude hiding (lookup) import Control.DeepSeq +import Data.Kind (Type) import Data.Proxy (Proxy (..)) import Data.Typeable (TypeRep, Typeable, typeRep) import GHC.Base (Any) @@ -30,7 +30,7 @@ import qualified Data.Map.Lazy as LMap -- | Map-like data structure with types served as the keys. -newtype TypeRepMap (f :: k -> *) = TypeRepMap +newtype TypeRepMap (f :: k -> Type) = TypeRepMap { unMap :: LMap.Map TypeRep Any } diff --git a/typerep-extra-impls/Data/TypeRep/OptimalVector.hs b/typerep-extra-impls/Data/TypeRep/OptimalVector.hs index a9a8648..a707efe 100644 --- a/typerep-extra-impls/Data/TypeRep/OptimalVector.hs +++ b/typerep-extra-impls/Data/TypeRep/OptimalVector.hs @@ -1,9 +1,8 @@ -{-# LANGUAGE BangPatterns #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE KindSignatures #-} -{-# LANGUAGE MagicHash #-} -{-# LANGUAGE PolyKinds #-} -{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE BangPatterns #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE MagicHash #-} +{-# LANGUAGE PolyKinds #-} +{-# LANGUAGE TypeFamilies #-} {- | Copyright: (c) 2017-2020 Kowainik @@ -62,7 +61,7 @@ empty :: TypeRepMap f empty = TypeRepMap mempty mempty mempty -- | Inserts the value with its type as a key. -insert :: forall a f . Typeable a => a -> TypeRepMap f -> TypeRepMap f +insert :: forall a f . a -> TypeRepMap f -> TypeRepMap f insert = undefined -- | Looks up the value at the type. @@ -112,7 +111,7 @@ binarySearch (Fingerprint a b) fpAs fpBs = data TF f where TF :: Typeable a => f a -> TF f -fromF :: Typeable a => f a -> Proxy a +fromF :: f a -> Proxy a fromF _ = Proxy fromList :: forall f . [TF f] -> TypeRepMap f diff --git a/typerep-extra-impls/Data/TypeRep/Vector.hs b/typerep-extra-impls/Data/TypeRep/Vector.hs index a100fbd..5536f69 100644 --- a/typerep-extra-impls/Data/TypeRep/Vector.hs +++ b/typerep-extra-impls/Data/TypeRep/Vector.hs @@ -144,7 +144,7 @@ empty :: TypeRepVector f empty = TypeRepVect mempty mempty -- | Inserts the value with its type as a key. -insert :: forall a f . Typeable a => a -> TypeRepVector f -> TypeRepVector f +insert :: forall a f . a -> TypeRepVector f -> TypeRepVector f insert = undefined -- | Looks up the value at the type. @@ -164,7 +164,7 @@ size = Unboxed.length . fingerprints data TF f where TF :: Typeable a => f a -> TF f -fromF :: Typeable a => f a -> Proxy a +fromF :: f a -> Proxy a fromF _ = Proxy fromList :: forall f . [TF f] -> TypeRepVector f diff --git a/typerep-map.cabal b/typerep-map.cabal index 4234cb1..7450b0c 100644 --- a/typerep-map.cabal +++ b/typerep-map.cabal @@ -48,8 +48,23 @@ common common-options RecordWildCards ScopedTypeVariables TypeApplications - if impl(ghc >= 8.8.1) + ghc-options: -Wall + -Wcompat + -Widentities + -Wincomplete-uni-patterns + -Wincomplete-record-updates + if impl(ghc >= 8.0) + ghc-options: -Wredundant-constraints + if impl(ghc >= 8.2) + ghc-options: -fhide-source-paths + if impl(ghc >= 8.4) + ghc-options: -Wmissing-export-lists + -Wpartial-fields + if impl(ghc >= 8.8) ghc-options: -Wmissing-deriving-strategies + -Werror=missing-deriving-strategies + if impl(ghc >= 8.10) + ghc-options: -Wunused-packages library import: common-options