syntactic-2.0: benchmarks/JoiningTypes.hs
{-# LANGUAGE TemplateHaskell #-}
module JoiningTypes (main) where
import Criterion.Main
import Criterion.Config
import Data.Monoid
import Data.Syntactic
import Data.Syntactic.Functional
-- Normal DSL, not joined types.
data Expr1 t where
EI :: Int -> Expr1 (Full Int)
EB :: Bool -> Expr1 (Full Bool)
EAdd :: Expr1 (Int :-> Int :-> Full Int)
EEq :: (Eq t) => Expr1 (t :-> t :-> Full Bool)
EIf :: Expr1 (Bool :-> a :-> a :-> Full a)
type Expr1' a = AST Expr1 (Full a)
int :: Int -> Expr1' Int
int = Sym . EI
bool :: Bool -> Expr1' Bool
bool = Sym . EB
add :: Expr1' Int -> Expr1' Int -> Expr1' Int
add a b = Sym EAdd :$ a :$ b
eq :: (Eq a) => Expr1' a -> Expr1' a -> Expr1' Bool
eq a b = Sym EEq :$ a :$ b
if' :: Expr1' Bool -> Expr1' a -> Expr1' a -> Expr1' a
if' c a b = Sym EIf :$ c :$ a :$ b
instance Render Expr1 where
renderSym (EI n) = "EI"
renderSym (EB b) = "EB"
renderSym (EAdd) = "EAdd"
renderSym (EEq) = "EEq"
renderSym (EIf) = "EIf"
interpretationInstances ''Expr1
instance Eval Expr1 where
evalSym (EI n) = n
evalSym (EB b) = b
evalSym EAdd = (+)
evalSym EEq = (==)
evalSym EIf = \c a b -> if c then a else b
instance EvalEnv Expr1 env where
compileSym p (EI n) = compileSymDefault p (EI n)
compileSym p (EB b) = compileSymDefault p (EB b)
compileSym p EAdd = compileSymDefault p EAdd
compileSym p EEq = compileSymDefault p EEq
compileSym p EIf = compileSymDefault p EIf
-- Joined types
data ExprI t where
EIJ :: Int -> ExprI (Full Int)
EAddJ :: ExprI (Int :-> Int :-> Full Int)
data ExprB t where
EBJ :: Bool -> ExprB (Full Bool)
EEqJ :: (Eq t) => ExprB (t :-> t :-> Full Bool)
EIfJ :: ExprB (Bool :-> a :-> a :-> Full a)
type ExprJ = ExprI :+: ExprB
type ExprJ' a = AST ExprJ (Full a)
intJ :: Int -> ExprJ' Int
intJ = Sym . inj . EIJ
boolJ :: Bool -> ExprJ' Bool
boolJ = Sym . inj . EBJ
addJ :: ExprJ' Int -> ExprJ' Int -> ExprJ' Int
addJ a b = Sym (inj EAddJ) :$ a :$ b
eqJ :: (Eq a) => ExprJ' a -> ExprJ' a -> ExprJ' Bool
eqJ a b = Sym (inj EEqJ) :$ a :$ b
ifJ :: ExprJ' Bool -> ExprJ' a -> ExprJ' a -> ExprJ' a
ifJ c a b = Sym (inj EIfJ) :$ c :$ a :$ b
instance Render ExprI where
renderSym (EIJ n) = "EI"
renderSym (EAddJ) = "EAdd"
instance Render ExprB where
renderSym (EBJ b) = "EB"
renderSym (EEqJ) = "EEq"
renderSym (EIfJ) = "EIf"
interpretationInstances ''ExprI
interpretationInstances ''ExprB
instance Eval ExprI where
evalSym (EIJ n) = n
evalSym EAddJ = (+)
instance Eval ExprB where
evalSym (EBJ b) = b
evalSym EEqJ = (==)
evalSym EIfJ = \c a b -> if c then a else b
instance EvalEnv ExprI env where
compileSym p (EIJ n) = compileSymDefault p (EIJ n)
compileSym p EAddJ = compileSymDefault p EAddJ
instance EvalEnv ExprB env where
compileSym p (EBJ b) = compileSymDefault p (EBJ b)
compileSym p EEqJ = compileSymDefault p EEqJ
compileSym p EIfJ = compileSymDefault p EIfJ
-- Joined types (4 joins)
data Expr4J1 t where
E4JI :: Int -> Expr4J1 (Full Int)
data Expr4J2 t where
E4JB :: Bool -> Expr4J2 (Full Bool)
data Expr4J3 t where
E4JAdd :: Expr4J3 (Int :-> Int :-> Full Int)
data Expr4J4 t where
E4JEq :: (Eq t) => Expr4J4 (t :-> t :-> Full Bool)
data Expr4J5 t where
E4JIf :: Expr4J5 (Bool :-> a :-> a :-> Full a)
type Expr4J = Expr4J1 :+: Expr4J2 :+: Expr4J3 :+: Expr4J4 :+: Expr4J5
type Expr4J' a = AST Expr4J (Full a)
int4 :: Int -> Expr4J' Int
int4 = Sym . inj . E4JI
bool4 :: Bool -> Expr4J' Bool
bool4 = Sym . inj . E4JB
add4 :: Expr4J' Int -> Expr4J' Int -> Expr4J' Int
add4 a b = Sym (inj E4JAdd) :$ a :$ b
eq4 :: (Eq a) => Expr4J' a -> Expr4J' a -> Expr4J' Bool
eq4 a b = Sym (inj E4JEq) :$ a :$ b
if4 :: Expr4J' Bool -> Expr4J' a -> Expr4J' a -> Expr4J' a
if4 c a b = Sym (inj E4JIf) :$ c :$ a :$ b
instance Render Expr4J1 where
renderSym (E4JI n) = "EI"
instance Render Expr4J2 where
renderSym (E4JB b) = "EB"
instance Render Expr4J3 where
renderSym (E4JAdd) = "EAdd"
instance Render Expr4J4 where
renderSym (E4JEq) = "EEq"
instance Render Expr4J5 where
renderSym (E4JIf) = "EIf"
interpretationInstances ''Expr4J1
interpretationInstances ''Expr4J2
interpretationInstances ''Expr4J3
interpretationInstances ''Expr4J4
interpretationInstances ''Expr4J5
instance Eval Expr4J1 where
evalSym (E4JI n) = n
instance Eval Expr4J2 where
evalSym (E4JB b) = b
instance Eval Expr4J3 where
evalSym E4JAdd = (+)
instance Eval Expr4J4 where
evalSym E4JEq = (==)
instance Eval Expr4J5 where
evalSym E4JIf = \c a b -> if c then a else b
instance EvalEnv Expr4J1 env where
compileSym p (E4JI n) = compileSymDefault p (E4JI n)
instance EvalEnv Expr4J2 env where
compileSym p (E4JB b) = compileSymDefault p (E4JB b)
instance EvalEnv Expr4J3 env where
compileSym p E4JAdd = compileSymDefault p E4JAdd
instance EvalEnv Expr4J4 env where
compileSym p E4JEq = compileSymDefault p E4JEq
instance EvalEnv Expr4J5 env where
compileSym p E4JIf = compileSymDefault p E4JIf
-- Expressions
syntacticExpr :: Int -> Expr1' Int
syntacticExpr 0 = if' (eq (int 5) (int 4)) (int 5) (int 0)
syntacticExpr n = (add (syntacticExpr (n-1)) (syntacticExpr (n-1)))
syntacticExprJ :: Int -> ExprJ' Int
syntacticExprJ 0 = ifJ (eqJ (intJ 5) (intJ 4)) (intJ 5) (intJ 0)
syntacticExprJ n = (addJ (syntacticExprJ (n-1)) (syntacticExprJ (n-1)))
syntacticExpr4J :: Int -> Expr4J' Int
syntacticExpr4J 0 = if4 (eq4 (int4 5) (int4 4)) (int4 5) (int4 0)
syntacticExpr4J n = (add4 (syntacticExpr4J (n-1)) (syntacticExpr4J (n-1)))
main :: IO ()
main = defaultMainWith (defaultConfig {cfgSummaryFile = Last $ Just "bench-results/joiningTypes.csv"}) (return ())
[ bgroup "eval 10" [ bench "syntactic 0 joins" $ nf evalDen (syntacticExpr 10)
, bench "syntactic 1 join" $ nf evalDen (syntacticExprJ 10)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 10)]
, bgroup "eval 15" [ bench "syntactic 0 joins" $ nf evalDen (syntacticExpr 15)
, bench "syntactic 1 join" $ nf evalDen (syntacticExprJ 15)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 15)]
, bgroup "eval 20" [ bench "syntactic 0 joins" $ nf evalDen (syntacticExpr 20)
, bench "syntactic 1 join" $ nf evalDen (syntacticExprJ 20)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 20)]
, bgroup "size 10" [ bench "syntactic 0 joins" $ nf size (syntacticExpr 10)
, bench "syntactic 1 join" $ nf size (syntacticExprJ 10)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 10)]
, bgroup "size 15" [ bench "syntactic 0 joins" $ nf size (syntacticExpr 15)
, bench "syntactic 1 join" $ nf size (syntacticExprJ 15)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 15)]
, bgroup "size 20" [ bench "syntactic 0 joins" $ nf size (syntacticExpr 20)
, bench "syntactic 1 join" $ nf size (syntacticExprJ 20)
, bench "syntactic 4 joins" $ nf evalDen (syntacticExpr4J 20)]]