My adventure in Haskell programming hasn't been all epic. I am implementing Simple Lambda Calculus, and I am glad to have finished Syntax
, Evaluation
, as well as Substitution
, hoping they are correct. What remains is typing
as defined inside the red box (in the figure below), for which I am looking for guidance.
Heading
Please correct me if I am wrong,
(1) but what I gathered is that (T-Var)
, returns the type of given a variable x
. What construct in Haskell returns type
? I know that in prelude
it is :t x
, but I am looking for one that works under main = do
.
(2) If I were to define a function type_of
, it's most likely that I need to define the expected and return type, as an example,
type_of (Var x) :: type1 -> type2
type1
should be generic and type2
must be whatever object type that stores type information of a variable. For this, I am lost on how to define type1
and type2
.
(3) For (T-APP) and (T-ABS), I assume I apply substitution on Abstraction String Lambda
and Application Lambda Lambda
respectively. The type of the reduced form is the returned type. Is that correct?
Thanks in advance...
The key thing to take away from the simply typed lambda calculus is that the types are annotated on the lambda binders itself, every lambda term has a type. The typing rules that Pierce provides are are how to mechanically type-check that the expression is well-typed. type inference is a topic he covers later in the book, which is recovering the types from untyped expressions.
Aside, what Pierce doesn't give in this example is a couple ground types (
Bool
,Int
) , which are helpful when implementing the algorithm, so we'll just append those to our definition as well.If we translate this into Haskell we get:
The
Γ
that pierce threads through the equations is for type environment which we can represent in Haskell as a simple list structure.The empty environment
Ø
is then simply[]
. When Pierce writesΓ, x : T ⊢ ...
he means the environment extended with the definition ofx
bound to the typeT
. In Haskell we would implement it like:To write the checker from TAPL we implement a little error monad stack.
When we call
checkExpr
on a expression we either get back the valid type of the expression or aTypeError
indicating what is wrong with the function.For instance if we have the term:
We expect our type checker to validate that it it has output type
TInt
.But to fail for a term like:
Since
TInt
is not equal to(TInt -> TInt)
.That's all there really is to typechecking the STLC.