I have two related quetions. I made my way to STLC and Typechecking from Programming Lang Foundations, yet I am more or less mentally stuck at the STLC chapter, hence many things related to it are flying over my head.
Specific question:
In this chapter we are implementing a type checker, we have basic terms and contexts.
match t with
| tm_var x =>
match Gamma x with
| Some T => return T
| None => fail
end
| <{ \ x1 : T1, t2 }> =>
T2 <- type_check (x1 |-> T1 ; Gamma) t2 ;;
return <{{T1 -> T2}}>
| <{ t1 t2 }> =>
T1 <- type_check Gamma t1 ;;
T2 <- type_check Gamma t2 ;;
match T1 with
| <{{T11 -> T12}}> =>
if eqb_ty T11 T2 then return T12 else fail
| _ => fail
end
as such. I am not sure when to leave the context as plain Gamma and when to add a variable+type binding to it. For example in the function for lists, the given example is
T0 <- type_check Gamma t0 ;;
match T0 with
| <{{List T}}> =>
T1 <- type_check Gamma t1 ;;
T2 <- type_check (x21 |-> T ; x22 |-> <{{List T}}> ; Gamma) t2 ;;
if eqb_ty T1 T2 then return T1 else fail
| _ => fail
end
When I defined the sum type, I wrote
| <{ case t0 of | inl x1 => t1 | inr x2 => t2 }> =>
T0 <- type_check Gamma t0 ;;
match T0 with
|( Ty_Sum T1 T2) =>
T1' <- type_check Gamma t1 ;;
T2' <- type_check Gamma t2 ;;
if (andb (eqb_ty T1 T1') (eqb_ty T2 T2'))
then return ( Ty_Sum T1 T2) else fail
| _ => fail
end
Should I have modified the second Gamma to have t1 |-> T1 , or is this right, or is it all wrong?
Second and vague question: What can I do to understand the coding semantics of this better? I get the whole concept on a theoretical level, I can also mechanically replicate the code I have seen before, but I feel like the intuition isn't there yet.
TIA!
https://softwarefoundations.cis.upenn.edu/plf-current/Typechecking.html
This is the chapter I'm at, and where the code is coming from.