These notes give a brief recap of the simply-typed λ-calculus, its typing and evaluation, and pointers to where each rule is implemented in Stlc3.hs.
The syntax of λ-calculus expressions is as follows.
Expression | Meaning | Constructor |
1 , 2 , 3
|
Integer constants | EInt |
True , False
|
Boolean constants | EBool |
e1 + e2
|
Addition | EAdd |
e1 - e2
|
Subtraction | ESubt |
e1 * e2
|
Multiplication | EMult |
isz e
|
Zero test | EIs0 |
if e1 then e2 else e3
|
Conditional | EIf |
\x : t -> e
|
Function abstraction | ELam |
e1 e2
|
Function application | EApp |
let x = e1 in e2
|
Name binding | ELet |
(e1, e2)
|
Pair introduction | EPair |
let (x1, x2) = e1 in e2
|
Pair elimination | ELetPair |
()
|
Unit introduction | EUnit |
e1; e2
|
Unit elimination | ELetUnit |
fix e
|
Fixed point | EFix |
Note: the following two forms were introduced in Hw1, and follow the naming scheme therefrom. | ||
Inl[t+u] e , Inr[t+u] e
|
Sum introduction | CInl, CInr |
case e of Inl x1 -> e1 | Inr x2 -> e2
|
Sum elimination | CCase |
Type | Meaning | Constructor |
Int
|
Integers | TInt |
Bool
|
Booleans | TBool |
t1 -> t2
|
Functions | TFun |
t1 * t2
|
Products | TProd |
The following type was introduced in Hw1, and follows the naming scheme therefrom. | ||
t1 + t2
|
Sums | CTSum |
Typing judgments take the form $\Gamma \vdash e : t$, where $\Gamma$ is a typing environment (i.e., an association of variable names to types), $e$ is a λ-calculus expression, and $t$ is a λ-calculus type.
Not all valid λ-calculus expressions built following the rules above are meaningful. For
example, neither True + 4
or \x : Bool -> x + x
are meaningful
expressions. Typing can be thought of as characterizing those terms which do have meaning.
Alternatively, if we assume the evaluating an non-meaningful term would give rise to an error, typing can be thought of as an approximation of evaluation that determines whether or not expressions will give rise to errors.
Typing is implemented by the function check :: TEnv -> Expr -> Maybe Type, where TEnv is a list of identifiers and types, and the result of Just t if the input expression has type t, and Nothing otherwise.
Typing rule | Code reference |
$$\frac{ }{\Gamma \vdash 1 : \Int}$$ | Stlc3.hs, 42–43 |
$$\frac{\Gamma \vdash e_1 : \Int \quad \Gamma \vdash e_2 : \Int}{\Gamma \vdash e_1 + e_2 : \Int}$$ | Stlc3.hs, 44–47 |
$$\frac{\Gamma \vdash e_1 : \Int \quad \Gamma \vdash e_2 : \Int}{\Gamma \vdash e_1 - e_2 : \Int}$$ | Stlc3.hs, 48–51 |
$$\frac{\Gamma \vdash e_1 : \Int \quad \Gamma \vdash e_2 : \Int}{\Gamma \vdash e_1 * e_2 : \Int}$$ | Stlc3.hs, 52–55 |
$$\frac{ }{\Gamma \vdash \mathtt{True} : \Bool}$$ | Stlc3.hs, 56–57 |
$$\frac{\Gamma \vdash e : \Int}{\Gamma \vdash \mathtt{isz}\,e : \Bool}$$ | Stlc3.hs, 58–60 |
$$\frac{\Gamma \vdash e_1 : \Bool \quad \Gamma \vdash e_2 : t \quad \Gamma \vdash e_3 : t} {\Gamma \vdash \If{e_1}{e_2}{e_3} : t}$$ | Stlc3.hs, 61–65 |
$$\frac{(x : t) \in \Gamma}{\Gamma \vdash x : t}$$ | Stlc3.hs, 66–67 |
$$\frac{\Gamma, x : t \vdash e : u}{\Gamma \vdash \mathtt{\backslash x : t \to e : t \to u}}$$ | Stlc3.hs, 68–70 |
$$\frac{\Gamma \vdash e_1 : t \to u \quad \Gamma \vdash e_2 : t}{\Gamma \vdash e_1\,e_2 : u}$$ | Stlc.hs, 71–74 |
$$\frac{\Gamma \vdash e_1 : t \quad \Gamma, x : t \vdash e_2 : u} {\Gamma \vdash \Let{x}{e_1}{e_2} : u}$$ | Stlc.hs, 75–77 |
$$\frac{\Gamma \vdash e_1 : t_1 \quad \Gamma \vdash e_2 : t_2} {\Gamma \vdash (e_1, e_2) : t_1 * t_2}$$ | Stlc.hs, 78–81 |
$$\frac{\Gamma \vdash e_1 : t_1 * t_2 \quad \Gamma, x_1 : t_1, x_2 : t_2 \vdash e_2 : u} {\Gamma \vdash \Let{(x_1,x_2)}{e_1}{e_2} : u}$$ | Stlc.hs, 82–84 |
$$\frac{ }{\Gamma \vdash () : 1}$$ | Stlc.hs, 85–86 |
$$\frac{\Gamma \vdash e_1 : 1 \quad \Gamma \vdash e_2 : t} {\Gamma \vdash e_1; e_2 : t}$$ | Stlc.hs, 87–89 |
$$\frac{\Gamma \vdash e : (t \to u) \to (t \to u)} {\Gamma \vdash \mathtt{fix}\,e : t \to u}$$ | Stlc.hs, 90–92 |
$$\frac{\Gamma \vdash e : t}{\Gamma \vdash \Inl t u e : t + u}$$ | Hw1Solutions/Core.hs, 63–65 |
$$\frac{\Gamma \vdash e : u}{\Gamma \vdash \Inr t u e : t + u}$$ | Hw1Solutions/Core.hs, 66–68 |
$$\frac{\Gamma \vdash e : t_1 + t_2 \quad \Gamma, x_1 : t_1 \vdash e_1 : u \quad \Gamma, x_2 : t_2 \vdash e_2 : u} {\Gamma \vdash \CCase e {x_1} {e_1} {x_2} {e_2} : u}$$ | Hw1Solutions/Core.hs, 69–73 |
Evaluation judgments take the form $e \Eval v$, where $e$ is a λ-calculus expression and $v$ is a value. They are defined in terms of substitution $[x \mapsto v]e$, which denotes the expression $e$ in which all occurrences of variable $x$ have been replaced by value $v$.
Values are as follows:
Value | Meaning | Constructor |
$1$, $2$, $3$ | Integer values | VInt |
$\mathtt{True}$, $\mathtt{False}$ | Boolean values | VBool |
$\lambda x.e$ | Function values | VFun |
See the notes on environments for discussion of the implementation of function values | ||
$\langle v_1, v_2 \rangle$ | Pair values | VPair |
$\langle \rangle$ | Unit value | VUnit |
$\Vinl v$, $\Vinr v$ | Sum values | VInl, VInr |
Our implementation of evaluation uses environments rather than using substitutions directly. So, evaluation is implemented by a function eval of type VEnv -> Expr -> Value, where VEnv maps variable identifiers to values.
Evaluation rule | Code reference | |
$$\frac{ } {1 \Eval 1}$$ | Stlc3.hs, 111–112 | |
$$\frac{e_1 \Eval v_1 \quad e_2 \Eval v_2} {e_1 + e_2 \Eval v_1 + v_2}$$ | Stlc3.hs, 113–116 | |
$$\frac{e_1 \Eval v_1 \quad e_2 \Eval v_2} {e_1 - e_2 \Eval v_1 - v_2}$$ | Stlc3.hs, 117–120 | |
$$\frac{e_1 \Eval v_1 \quad e_2 \Eval v_2} {e_1 * e_2 \Eval v_1 \times v_2}$$ | Stlc3.hs, 121–124 | |
$$\frac{ } {\mathtt{True} \Eval \mathtt{True}}$$ | Stlc3.hs, 125–126 | |
$$\frac{e \Eval 0} {\mathtt{isz}\,e \Eval \mathtt{True}} \qquad \frac{e \Eval n \quad n \not= 0} {\mathtt{isz}\,e \Eval \mathtt{False}}$$ | Stlc3.hs, 127–129 | |
$$\frac{e_1 \Eval \mathtt{True} \quad e_2 \Eval v} {\If{e_1}{e_2}{e_3} \Eval v} \qquad \frac{e_1 \Eval \mathtt{False} \quad e_3 \Eval v} {\If{e_1}{e_2}{e_3} \Eval v}$$ | Stlc3.hs, 130–132 | |
$$\frac{ } {\mathtt{\backslash x : t \to e} \Eval \lambda x.e}$$ | Stlc3.hs, 135–136 | |
$$\frac{e_1 \Eval \lambda x. e \quad e_2 \Eval w \quad [x \mapsto w]e \Eval v} {e_1\,e_2 \Eval v}$$ | Stlc3.hs, 137–140 | |
$$\frac{e_1 \Eval w \quad [x \mapsto w]e_2 \Eval v} {\Let{x}{e_1}{e_2} \Eval v}$$ | Stlc3.hs, 141–143 | |
$$\frac{e_1 \Eval v_1 \quad e_2 \Eval v_2} {(e_1, e_2) \Eval \langle v_1, v_2 \rangle}$$ | Stlc3.hs, 144–147 | |
$$\frac{e_1 \Eval \langle w_1,w_2 \rangle \quad [x_1 \mapsto w_1, x_2 \mapsto w_2]e_2 \Eval v} {\Let{(x_1,x_2)}{e_1}{e_2} \Eval v}$$ | Stlc3.hs, 148–150 | |
$$\frac{ } {() \Eval \langle \rangle}$$ | Stlc3.hs, 151–152 | |
$$\frac{e_1 \Eval \langle\rangle \quad e_2 \Eval v} {e_1; e_2 \Eval v}$$ | Stlc3.hs, 153–155 | |
$$\frac{ } {\mathtt{fix}\,e \Eval \lambda x. e\,(\mathtt{fix}\,e)\,x}$$ | Stlc3.hs, 156–157 | |
See the notes on recursion for a more detailed discussion of fixed points. | ||
$$\frac{e \Eval v} {\Inl t u e \Eval \Vinl v} \qquad \frac{e \Eval v} {\Inl t u e \Eval \Vinr v}$$ | Hw1Solutions/Core.hs, 119–124 | |
$$\frac{e \Eval \Vinl w \quad
[x_1 \mapsto w]e_1 \Eval v}
{\CCase{e}{x_1}{e_1}{x_2}{e_2} \Eval v}$$
$$\frac{e \Eval \Vinr w \quad [x_2 \mapsto w]e_2 \Eval v} {\CCase{e}{x_1}{e_1}{x_2}{e_2} \Eval v}$$ |
Hw1Solutions/Core.hs, 125–129 |