ivo/src/LambdaCalculus/Evaluator/Base.hs

53 lines
1.5 KiB
Haskell

module LambdaCalculus.Evaluator.Base
( Identity (..)
, Expr (..), ExprF (..), VoidF, Text
, Eval, EvalExpr, EvalExprF, EvalX, EvalXF (..)
, pattern AppFE, pattern Cont, pattern ContF
) where
import LambdaCalculus.Expression.Base
import Data.Functor.Identity (Identity (..))
data Eval
type EvalExpr = Expr Eval
type instance AppArgs Eval = EvalExpr
type instance AbsArgs Eval = Text
type instance LetArgs Eval = VoidF EvalExpr
type instance XExpr Eval = EvalX
type EvalX = EvalXF EvalExpr
type EvalExprF = ExprF Eval
type instance AppArgsF Eval = Identity
type instance LetArgsF Eval = VoidF
type instance XExprF Eval = EvalXF
newtype EvalXF r
-- | A continuation. This is identical to a lambda abstraction,
-- with the exception that it performs the side-effect of
-- deleting the current continuation.
--
-- Continuations do not have any corresponding surface-level syntax,
-- but may be printed like a lambda with the illegal variable `!`.
= Cont_ r
deriving (Eq, Functor, Foldable, Traversable, Show)
instance RecursivePhase Eval where
projectAppArgs = Identity
embedAppArgs = runIdentity
pattern Cont :: EvalExpr -> EvalExpr
pattern Cont e = ExprX (Cont_ e)
pattern ContF :: r -> EvalExprF r
pattern ContF e = ExprXF (Cont_ e)
pattern AppFE :: r -> r -> EvalExprF r
pattern AppFE ef ex = AppF ef (Identity ex)
{-# COMPLETE Var, App, Abs, Let, Cont #-}
{-# COMPLETE VarF, AppF, AbsF, LetF, ContF #-}
{-# COMPLETE VarF, AppFE, AbsF, LetF, ExprXF #-}
{-# COMPLETE VarF, AppFE, AbsF, LetF, ContF #-}