module WithArity (main) where import Criterion.Main import Criterion.Types import Language.Syntactic hiding (E) import Language.Syntactic.Functional main :: IO () main = defaultMainWith (defaultConfig {csvFile = Just "bench-results/withArity.csv"}) [ bgroup "eval 5" [ bench "gadt" $ nf evl (gExpr 5) , bench "Syntactic" $ nf evalDen (sExpr 5) ] , bgroup "eval 6" [ bench "gadt" $ nf evl (gExpr 6) , bench "Syntactic" $ nf evalDen (sExpr 6) ] , bgroup "eval 7" [ bench "gadt" $ nf evl (gExpr 7) , bench "Syntactic" $ nf evalDen (sExpr 7) ] , bgroup "size 5" [ bench "gadt" $ nf gSize (gExpr 5) , bench "Syntactic" $ nf size (sExpr 5) ] , bgroup "size 6" [ bench "gadt" $ nf gSize (gExpr 6) , bench "Syntactic" $ nf size (sExpr 6) ] , bgroup "size 7" [ bench "gadt" $ nf gSize (gExpr 7) , bench "Syntactic" $ nf size (sExpr 7) ]] -- Expressions gExpr :: Int -> E Int gExpr 0 = E0 1 gExpr 1 = E2 (E2 (E0 1) (E0 1)) (E1 (E0 1)) gExpr n = E10 (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) (gExpr (n-1)) sExpr :: Int -> T' Int sExpr 0 = t0 1 sExpr 1 = t2 (t2 (t0 1) (t0 1)) (t1 (t0 1)) sExpr n = t10 (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) (sExpr (n-1)) gSize :: E a -> Int gSize (E0 _) = 1 gSize (E1 a) = gSize a gSize (E2 a b) = gSize a + gSize b gSize (E3 a b c) = gSize a + gSize b + gSize c gSize (E5 a b c d e) = gSize a + gSize b + gSize c + gSize d + gSize e gSize (E10 a b c d e f g h i j) = gSize a + gSize b + gSize c + gSize d + gSize e + gSize f + gSize g + gSize h + gSize i + gSize j -- Comparing Syntactic with GADTs -- GADTs data E a where E0 :: a -> E a E1 :: E a -> E a E2 :: E a -> E a -> E a E3 :: E a -> E a -> E a -> E a E5 :: E a -> E a -> E a -> E a -> E a -> E a E10 :: E a -> E a -> E a -> E a -> E a -> E a -> E a -> E a -> E a -> E a -> E a evl :: E Int -> Int evl (E0 n) = n evl (E1 a) = evl a evl (E2 a b) = evl a + evl b evl (E3 a b c) = evl a + evl b + evl c evl (E5 a b c d e) = evl a + evl b + evl c + evl d + evl e evl (E10 a b c d e f g h i j) = evl a + evl b + evl c + evl d + evl e + evl f + evl g + evl h + evl i + evl j -- Syntactic data T a where T0 :: Num a => a -> T (Full a) T1 :: Num a => T (a :-> Full a) T2 :: Num a => T (a :-> a :-> Full a) T3 :: Num a => T (a :-> a :-> a :-> Full a) T5 :: Num a => T (a :-> a :-> a :-> a :-> a :-> Full a) T10 :: Num a => T (a :-> a :-> a :-> a :-> a :-> a :-> a :-> a :-> a :-> a :-> Full a) type T' a = AST T (Full a) t0 :: Num a => a -> T' a t0 = Sym . T0 t1 :: Num a => T' a -> T' a t1 a = Sym T1 :$ a t2 :: Num a => T' a -> T' a -> T' a t2 a b = Sym T2 :$ a :$ b t3 :: Num a => T' a -> T' a -> T' a -> T' a t3 a b c = Sym T3 :$ a :$ b :$ c t5 :: Num a => T' a -> T' a -> T' a -> T' a -> T' a -> T' a t5 a b c d e = Sym T5 :$ a :$ b :$ c :$ d :$ e t10 :: Num a => T' a -> T' a -> T' a -> T' a -> T' a -> T' a -> T' a -> T' a -> T' a -> T' a -> T' a t10 a b c d e f g h i j = Sym T10 :$ a :$ b :$ c :$ d :$ e :$ f :$ g :$ h :$ i:$ j instance Render T where renderSym (T0 a) = "T0" renderSym T1 = "T1" renderSym T2 = "T2" renderSym T3 = "T3" renderSym T5 = "T5" renderSym T10 = "T10" instance Equality T instance StringTree T instance Eval T where evalSym (T0 a) = a evalSym T1 = id evalSym T2 = (+) evalSym T3 = \a b c -> a + b + c evalSym T5 = \a b c d e -> a + b + c + d + e evalSym T10 = \a b c d e f g h i j -> a + b + c + d + e + f + g + h + i + j instance EvalEnv T env where compileSym p (T0 a) = compileSymDefault signature p (T0 a) compileSym p T1 = compileSymDefault signature p T1 compileSym p T2 = compileSymDefault signature p T2 compileSym p T3 = compileSymDefault signature p T3 compileSym p T5 = compileSymDefault signature p T5 compileSym p T10 = compileSymDefault signature p T10