These are notes taken from Adam Jones introduction of Lambda Calculus
Intro to Lambda Calculus
Write an identity function that takes a 3
(\x -> x) 3
take x → return x
(\odd -> odd) 3
Literal = 3 Variable = Odd Abstraction/ Function Definition = ( \odd → odd) Application = (\odd → odd) 3
Parts of Expression
(\x -> (\y ->x)) 1 2
(\y -> 1) 2
(2 -> 1)
1
Exercise
(\odd -> odd 3)(\x -> equals (mod x 2 ) 1)
(\x -> equals (mod x 2) 1) 3
equals (mod 3 2) 1
equals 1 1
True
Step 1: Original Expression
Step 2: Apply the function to the argument
Step 3: Simplify the inner expression
Final Simplified Expression
Grammar of the Lambda Calculus
e = x --variable
| e_1 e_2 --application
| \x -> e --abstraction
Free and Bound Variables in Lambda Calculus
- Function abstraction binds variables
- Variables that arenot bounds are considered free or unbound
(\x -> x) 3
x = bound by function abstraction 3 = unbounded
(\x -> (\z -> y)) h
y = unbounded h = unbounded
Free Variables Solutions
[variable] [function application] [function abstraction ]
The free variables is only
Let Expressions in Lambda Calculus
let x = 3 in odd x
(\x -> odd x) 3
Let Expressions and Polymorphism
let x = (\x -> x)
in x (odd (x 3))
e = x --variable
| e_1 e_2 --application
| \x -> e --abstraction
| let x = e_1 in e_2 --let
Type Inference
Example | Type |
---|---|
3 | Int |
True | Bool |
odd | function from Int to Bool |
odd 3 | Bool |
odd True | not well-typed |
\x → x | function, which for an , is from to |
Types in Hindley-Milner
A type system for the lambda calculus with let statements
- Type Variables
- Type Function Applications
- List Bool
- Int → Bool
- Bool
- List
Monotypes in Hindley-Milner
where is the set of type functions, which must contain → For example = → , Int, Bool, List, Map, 2-Tuple, 3-Tuple
For-all Quantifiers
<T>(arg: T): T
T = TypeVar('T')
Callable[[T],T]
id (odd (id 3))
Hindley-Milner Types Syntax
Assignments, Contexts, Typing Judgement and Rules in Type Systems
Expression : Type Assignment = Age : Int
age :: Int
context = → a list of assignments
age is an integer contained in the context
Typing Judgements
when an assignment follows given the context, we can make a typing judgement
From the context gamma, the expression e has type
Context | Judgements |
---|---|
Premise ⇒ Conclusion (judgement) | |
⇒ |
Free and Bound Type Variables in Type Systems
Free Variables in Types
[var] [app] [quantifier]
Free Variables in Contexts
Exercise 1
What are the free variables in this type ?
Use rules by quantifier: by app: by app:
Substitutions in Logic
A map from variables to terms
Applying Substitutions to Type Systems
Combining Substitutions in Logic
Unifying Substitutions and the Unification Process
A substitution unifies two values if when applied to both it results in equal results
→ S is a not a unifying substitution
→ S is a unifying substitution
There is no unifying substitution as they are of different structure.
Algorithm Signature
A unifying S may not exist at all, or may not be finite.
Applying Unification to Type Systems
No unifying substitution exists
Unification can 'merge' types while preserving all type constrainsts
Unification Algorithm for Hindley-Milner Types
The Algorithm
unify(a: MonoType, b: MonoType) → Substitution: if a is a type variable: if b is the same type variable: return {} if b contains a: throw error “occurs check failed, cannot create infinite type” returns {} if b is a type variable: return unify(b,a) if a and b are both type function applications: if a and b have different type functions: throw error “failed to unify, different type functions” let S = {} for i in range(number of type function arguments): S = combine(S,unify(S(a.arguments[i]),S(b.arguments[i]))) return S
function unify(a: MonoType, b: MonoType): Substitution {
if (a instanceof TypeVar) {
if (b instanceof TypeVar && a.name == b.name)
return {};
if (contains(b, a))
throw new TypeInferenceError('occurs check failed,' +
' cannot create infinite type');
return { [a.name]: b }
}
if (b instanceof TypeVar)
return unify(b, a);
if (a instanceof TypeFuncApp && b instanceof TypeFuncApp) {
if (a.constructorName !== b.constructorName)
throw new TypeInferenceError('failed to unify,' +
' different type functions');
let S: Substitution = {};
for (let i = 0; i < a.args.length; i++) {
S = combine(S, unify(apply(S, a.args[i]), apply(S, b.args[i])));
}
return S;
}
}
Type Order and the Relation in Hindley-Milner
More General |
---|
Less General |
Type on left is more general than type on right
Syntax for Type Order
Formal Definition
is more general than if there is a substitution that maps the for-all quantified variables in , and
Instantiation in Type Systems and Hindley-Milner
find typs that are less generals
⇒ with
If , an expression of type can be used where one of type is needed.
Generalisation of Types in Hindley-Milner
Add for all quantifier into a free type variable in a type
Can only generalise a type when the type variable is not free in the context
generalise returns the most generalised version of the type
Intro to Hindley-Milner Typing Rules
Variable Typing Rule
- If “the variable '' has type of polytype ''” is in context
- then from the context '' it follows that “the variable '' has type of polytype ''”
Q: what is the type of age given the context of ''? A: Int
Application Typing Rule
-
If is of type and is of type
-
applied to is type
-
If premise
-
Then conclusion
← inference
Conclusion (premise)
Unifying Constraints with Typing Rules
- t0 ~ t2
- t1 ~ t3
- t1 → t2 ~ t4
- t4 ~ Int → Bool
- t3 ~ t5
- t5 ~ Int
Finding Type Errors with Typing Rules
- t0 ~ t2
- t1 ~ t3
- t1 → t2 ~ t4
- t4 ~ Int → Bool
- t3 ~ t5
- t5 ~ Bool
- t3 → t2 ~ t4 t4 ~ Int → Bool t3 ~ t5 t5 ~ Bool
- t3 → t2 ~ Int → Bool
- Int ~ t5 t5 ~ Bool 5) Int ~ Bool ⇒ Type Error
Function Abstraction Typing Rule
If from the context '' plus the assignment “variable ‘x’ has type ''” if follows that expression ‘e’ has type ''
then from the context '' it follows that the expression '' has type ''
The function parameters get replaced by the types
Q: What is the type of ’ given the context '' ?
Reading the Rule
The whole rule is saying:
- Premise: If, in a context where
n
has typeInt
, the expression\text{gt}\ 3\ n
has typeBool
… - Conclusion: …then the function
\n \rightarrow \text{gt}\ 3\ n
has the type\text{Int} \rightarrow \text{Bool}
, i.e., it is a function that takes an integer and returns a boolean.
Let Typing Rule
If we bind an expression to a variable x with type and doing so results in the let body having type
then the let statement as a whole has type
= gt : Int → (Int → Bool)
let a = 2 in gt 3 a : Bool
= 2 = gt 3 a x = a = Int = Bool
Instantiation Typing Rule
If , an expression of type can be used where one of type is needed.
If from it follows that has type and is more general than , then from the context it follows that has type
reverse: ages:
What is the type of ‘reverse ages’ given the context ?
Generalization Typing Rule
If e has type and type variable is not free in the context
then for-all quantify e’s type with variable