53 lines
1.5 KiB
Haskell
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 #-}
|