
(Figure 1)
A part of the simply typed lambda calculus (Figure 1), it is implemented in Haskell as given below.
evaluate expression = do
case expression of
(Application (Lambda x ltype term) value) | isValue value = True -> substitute term x value
(Application value e2) | isValue value = True -> let e22 = evaluate e2 in Application value e22
(Application e1 e2) -> let e11 = evaluate e1 in Application e11 e2
However, this doesn't work for these test cases,
1) print (evaluate (Application (Var "x") (Var "y")))
2) print (evaluate (Application (Constant 3) (Var "y")) "(Constant 3) is a value"
But, for the first test case, I know it's because (Var "x") as e1 is terminal so it cannot transition. Does it mean I should add a Stuck case? But I want to return an output suggesting the success of the transitions, if that's possible.
Thank you in advance...
If you're implementing your lambda calculus AST as something like
then the interpreter
evaluate :: Exp -> Outcan produce a number of values, some the result of poorly typed input. For instanceWe'll need to represent all of these types in the return type. A typical way to do that is to use a universal type like
which again emphasizes the need for the stuck case. If we examine the
Appbranch ofevaluateshow's how
Stuckcases both rise to the top and can arise from poorly typed terms.There are many ways to write a well-typed simply-typed lambda calculus type in Haskell. I'm quite fond of the Higher-Order Abstract Syntax Final Encoding. It's wonderfully symmetric.
In this formulation, it's not possible at all to write a type of
STLC rep => rep awhich isn't well-typed and never-sticking. The type ofinterpretindicates this as wellNo
Out-type in sight.