(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 -> Out
can 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
App
branch ofevaluate
show's how
Stuck
cases 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 a
which isn't well-typed and never-sticking. The type ofinterpret
indicates this as wellNo
Out
-type in sight.