-- | Interpreter to evaluate a term as a host-term.
module Language.Symantic.Interpreting.Eval where

import Control.Monad

-- * Type 'Eval'

-- | Interpreter's data.
newtype Eval a = Eval { unEval :: a }
instance Functor Eval where
	fmap f (Eval a) = Eval (f a)
instance Applicative Eval where
	pure = Eval
	(Eval f) <*> (Eval a) = Eval (f a)
instance Monad Eval where
	return = Eval
	(Eval a) >>= f = f a

-- | Interpreter.
eval :: Eval a -> a
eval = unEval

-- ** Constructors
eval0 :: a -> Eval a
eval0 = Eval

eval1 :: (a -> b) -> Eval a -> Eval b
eval1 = liftM

eval2 :: (a -> b -> c) -> Eval a -> Eval b -> Eval c
eval2 = liftM2

eval3 :: (a -> b -> c -> d) -> Eval a -> Eval b -> Eval c -> Eval d
eval3 = liftM3