{-# LANGUAGE GADTs #-} data Expr t where I :: Int -> Expr Int B :: Bool -> Expr Bool AddInt :: Expr Int -> Expr Int -> Expr Int IsZero :: Expr Int -> Expr Bool If :: Expr Bool -> Expr t -> Expr t -> Expr t eval :: Expr t -> t eval (I i) = i eval (B b) = b eval (AddInt e1 e2) = eval e1 + eval e2 eval (IsZero e) = eval e == 0 eval (If e1 e2 e3) = if eval e1 then eval e2 else eval e3