34 lines
1.1 KiB
Haskell
34 lines
1.1 KiB
Haskell
module LambdaCalculus.Expression
|
|
( Expr (..), ExprF (..), DefF (..), VoidF, Text
|
|
, Eval, EvalExpr, EvalX, EvalXF (..), Identity (..)
|
|
, pattern AppFE, pattern Cont, pattern ContF
|
|
, Parse, AST, ASTF, NonEmptyDefFs (..), NonEmpty (..), simplify
|
|
, pattern LetFP
|
|
, ast2eval, eval2ast
|
|
) where
|
|
|
|
import LambdaCalculus.Evaluator.Base
|
|
import LambdaCalculus.Syntax.Base
|
|
|
|
import Data.Functor.Foldable (cata, hoist)
|
|
import Data.List (foldl')
|
|
import Data.List.NonEmpty (toList)
|
|
|
|
-- | Convert from an abstract syntax tree to an evaluator expression.
|
|
ast2eval :: AST -> EvalExpr
|
|
ast2eval = cata \case
|
|
VarF name -> Var name
|
|
AppF ef exs -> foldl' App ef $ toList exs
|
|
AbsF ns e -> foldr Abs e $ toList ns
|
|
LetF ds e ->
|
|
let letExpr name val body' = App (Abs name body') val
|
|
in foldr (uncurry letExpr) e $ getNonEmptyDefFs ds
|
|
|
|
-- | Convert from an evaluator expression to an abstract syntax tree.
|
|
eval2ast :: EvalExpr -> AST
|
|
eval2ast = hoist \case
|
|
VarF name -> VarF name
|
|
AppFE ef ex -> AppF ef (ex :| [])
|
|
AbsF n e -> AbsF (n :| []) e
|
|
ContF e -> AbsF ("!" :| []) e
|