{-#LANGUAGE TypeOperators, MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, IncoherentInstances, UndecidableInstances, ScopedTypeVariables #-}
-----------------------------------------------------------------------------
--
-- Module      :  Base.Eval
-- Copyright   :
-- License     :  AllRightsReserved
--
-- Maintainer  :
-- Stability   :
-- Portability :
--
-- |
--
-----------------------------------------------------------------------------

module Base.Eval where

import Base.Expr

class Functor f => Eval f where
    evalAlgebra :: f Int -> Int

instance Eval Val where
    evalAlgebra (Val x) = x

instance Eval Add where
    evalAlgebra (Add x y) = x + y

instance (Eval f, Eval g) => Eval (f :+: g) where
    evalAlgebra (Inl x) = evalAlgebra x
    evalAlgebra (Inr y) = evalAlgebra y

eval :: Eval f => Expr f -> Int
eval = foldExpr evalAlgebra
