{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
module Expr (Expr(..), eval) where
data Expr a where
Num :: Int -> Expr Int
Plus :: Expr Int -> Expr Int -> Expr Int
Eq :: Expr Int -> Expr Int -> Expr Bool
If :: Expr Bool -> Expr e -> Expr e -> Expr e
eval :: Expr e -> e
eval :: forall e. Expr e -> e
eval (Num Int
n) = e
Int
n
eval (Plus Expr Int
e1 Expr Int
e2) = Expr e -> e
forall e. Expr e -> e
eval Expr e
Expr Int
e1 e -> e -> e
forall a. Num a => a -> a -> a
+ Expr e -> e
forall e. Expr e -> e
eval Expr e
Expr Int
e2
eval (Eq Expr Int
e1 Expr Int
e2) = Expr Int -> Int
forall e. Expr e -> e
eval Expr Int
e1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Expr Int -> Int
forall e. Expr e -> e
eval Expr Int
e2
eval (If Expr Bool
e1 Expr e
e2 Expr e
e3) = if Expr Bool -> Bool
forall e. Expr e -> e
eval Expr Bool
e1 then Expr e -> e
forall e. Expr e -> e
eval Expr e
e2 else Expr e -> e
forall e. Expr e -> e
eval Expr e
e3