This time on Types ... Polymorphic λ -calculus (polymorphic λ -binding). Let’s us type: λ f (( f true ) :: ( f nil ))
λ -bound variables in ML cannot be used polymorphically within a function abstraction E.g. λ f (( f true ) :: ( f nil )) and λ f ( f f ) are not typeable in the ML type system. Syntactically , because in rule Γ , x : τ 1 ` M : τ 2 ( fn ) Γ ` λ x ( M ) : τ 1 ! τ 2 the abstracted variable has to be assigned a trivial type scheme (recall x : τ 1 stands for x : 8 { } ( τ 1 )). Semantically , because 8 A ( τ 1 ) ! τ 2 is not semantically equivalent to an ML type when A 6 = { } .
Monomorphic types . . . τ ::= α | bool | τ ! τ | τ list . . . and type schemes σ ::= τ | 8 α ( σ ) Polymorphic types π ::= α | bool | π ! π | π list | 8 α ( π ) E.g. α ! α 0 is a type, 8 α ( α ! α 0 ) is a type scheme and a polymorphic type (but not a monomorphic type), 8 α ( α ) ! α 0 is a polymorphic type, but not a type scheme.
Identity, Generalisation and Specialisation Γ ` x : π if ( x : π ) 2 Γ ( id ) Γ ` M : π if α / 2 ftv ( Γ ) ( gen ) Γ ` M : 8 α ( π ) Γ ` M : 8 α ( π ) ( spec ) Γ ` M : π [ π 0 / α ]
Fact (see Wells (1994)): For the modified ML type system with polymorphic types and ( var � ) replaced by the axiom and rules on Slide 41, the type checking and typeability problems (cf. Slide 9) are equivalent and undecidable.
Explicitly versus implicitly typed languages Implicit: little or no type information is included in program phrases and typings have to be inferred (ideally, entirely at compile-time). (E.g. Standard ML.) Explicit: most, if not all, types for phrases are explicitly part of the syntax. (E.g. Java.) E.g. self application function of type ∀ α ( α ) → ∀ α ( α ) (cf. Example 7) Implicitly typed version: λ f ( f f ) Explicitly type version: λ f : ∀ α 1 ( α 1 ) ( Λ α 2 ( f ( α 2 → α 2 )( f α 2 )))
PLC syntax τ ::= α type variable Types | function type τ ! τ | 8 α ( τ ) 8 -type Expressions M ::= x variable | λ x : τ ( M ) function abstraction | M M function application | Λ α ( M ) type generalisation | M τ type specialisation ( α and x range over fixed, countably infinite sets TyVar and Var respectively.)
Functions on types In PLC, Λ α ( M ) is an anonymous notation for the function F mapping each type τ to the value of M [ τ / α ] (of some particular type). F τ denotes the result of applying such a function to a type. Computation in PLC involves beta-reduction for such functions on types ( Λ α ( M )) τ ! M [ τ / α ] as well as the usual form of beta-reduction from λ -calculus ( λ x : τ ( M 1 )) M 2 ! M 1 [ M 2 / x ]
PLC typing judgement takes the form Γ ` M : τ where I the typing environment Γ is a finite function from variables to PLC types. (We write Γ = { x 1 : τ 1 , . . . , x n : τ n } to indicate that Γ has domain of definition dom ( Γ ) = { x 1 , . . . , x n } and maps each x i to the PLC type τ i for i = 1 .. n .) I M is a PLC expression I τ is a PLC type.
PLC type system Γ ` x : τ if ( x : τ ) 2 Γ ( var ) Γ , x : τ 1 ` M : τ 2 if x / 2 dom ( Γ ) ( fn ) Γ ` λ x : τ 1 ( M ) : τ 1 ! τ 2 Γ ` M 1 : τ 1 ! τ 2 Γ ` M 2 : τ 1 ( app ) Γ ` M 1 M 2 : τ 2 Γ ` M : τ if α / 2 ftv ( Γ ) ( gen ) Γ ` Λ α ( M ) : 8 α ( τ ) Γ ` M : 8 α ( τ 1 ) ( spec ) Γ ` M τ 2 : τ 1 [ τ 2 / α ]
Exercise (5 mins) Consider the identity function id , which in the simply-typed lambda calculus is written λ x . x . Define id in the polymorphic lambda-calculus such that it has type: id : ∀ α ( α → α ) Give its type derivation tree. Hint: the polymorphic identity function has two layers of abstraction: first type abstraction over the type variable α , then over the value variable.
Some syntax considerations I Application is left associative M 1 M 2 M 3 = ( M 1 M 2 ) M 3 I Function type arrows are right associative = τ 1 → ( τ 2 → τ 3 ) τ 1 → τ 2 → τ 3 I Delimit binders with parentheses; alternatively dot with scope as far to right as possible ∀ α . τ = ∀ α ( τ ) I Multiple binders ∀ α ( ∀ β ( τ )) = ∀ α , β ( τ ) Λ α ( Λ β ( τ )) = Λ α , β ( τ )
α -equivalence Λ α ( λ ( x : α ) x ) = Λ β ( λ ( x : β ) x ) = Λ β ( λ ( y : β ) y ) 8 α ( α ! α ) = 8 β ( β ! β ) 8 α ( α ! β ! α ) 6 = 8 β ( β ! β ! β ) 6 = 8 α ( α ! γ ! α )
An incorrect ‘proof’ ( var ) x 1 : α , x 2 : α ` x 2 : α ( fn ) x 1 : α ` λ x 2 : α ( x 2 ) : α ! α ( wrong !) x 1 : α ` Λ α ( λ x 2 : α ( x 2 )) : 8 α ( α ! α )
Explicit types let us control the variables and choose a different (non-conflicting) variable name for the type of x2
Decidability of the PLC typeability and type-checking problems Theorem. For each PLC typing problem, Γ ` M : ?, there is at most one PLC type τ for which Γ ` M : τ is provable. Moreover there is an algorithm, typ , which when given any Γ ` M : ? as input, returns such a τ if it exists and FAIL s otherwise. Corollary. The PLC type checking problem is decidable: we can decide whether or not Γ ` M : τ is provable by checking whether typ ( Γ ` M : ?) = τ . (N.B. equality of PLC types up to alpha-conversion is decidable.)
PLC type-checking algorithm, I Variables: typ ( Γ , x : τ ` x : ?) def = τ Function abstractions: typ ( Γ ` λ x : τ 1 ( M ) : ?) def = let τ 2 = typ ( Γ , x : τ 1 ` M : ?) in τ 1 ! τ 2 Function applications: typ ( Γ ` M 1 M 2 : ?) def = let τ 1 = typ ( Γ ` M 1 : ?) in let τ 2 = typ ( Γ ` M 2 : ?) in if τ = τ 2 then τ 0 else FAIL τ ! τ 0 case τ 1 of 7! | 7! FAIL
PLC type-checking algorithm, II Type generalisations: typ ( Γ ` Λ α ( M ) : ?) def = let τ = typ ( Γ ` M : ?) in 8 α ( τ ) Type specialisations: typ ( Γ ` M τ 2 : ?) def = let τ = typ ( Γ ` M : ?) in case τ of 8 α ( τ 1 ) 7! τ 1 [ τ 2 / α ] | 7! FAIL
Polymorphic booleans bool def = 8 α ( α ! ( α ! α )) True def = Λ α ( λ x 1 : α , x 2 : α ( x 1 )) False def = Λ α ( λ x 1 : α , x 2 : α ( x 2 )) if def = Λ α ( λ b : bool , x 1 : α , x 2 : α ( b α x 1 x 2 ))
Recommend
More recommend