1 / 17

Polymorphic Type System

Polymorphic Type System. Goals. Allow expression of “ for all types T ” fun I x = x I : ’a -> ’a Allow expression of type-equality constraints fun fst (x,y) = x fst : ’a *’b -> ’a Support notion of instance of a type I 5 I : int -> int. Type constants

hedia
Download Presentation

Polymorphic Type System

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Polymorphic Type System L4Poly

  2. Goals • Allow expression of “for all types T” fun I x = x I : ’a -> ’a • Allow expression of type-equality constraints fun fst (x,y) = x fst : ’a *’b -> ’a • Support notion of instance of a type I 5 I : int -> int L4Poly

  3. Type constants int, bool, … Type variables ’a, …, ’’a, … Type constructors ->, *, … Principal type of an expression is the most general type, which ML system infers. Type Checking Rule An expression of a type can legally appear in all contexts where an instance of that type can appear. Polymorphic Type System L4Poly

  4. Signature of Equality = : ’a * ’a -> bool ? • Equality (“= ”) is not computable for all types. E.g., function values. • So types (’a,’b, …) are partitioned into • types that support equality (’’a, ’’b, …) • types that do not support equality. = : ’’a * ’’a -> bool • int, string, etc are equality types. They are closed under cartesian product, but not under function space constructor. L4Poly

  5. Type Inference I (3,5) = (3,5) (int*int)->(int*int) (int*int) Principal type of I is the generalization of all possible types of its uses. Curry2 : (’a * ’b -> ’c) -> (’a -> ’b -> ’c) Uncurry2 : (’a -> ’b -> ’c) -> (’a * ’b -> ’c) L4Poly

  6. Subtle Points • The type of a use of a function must be an instance of the principal type inferred in the definition. • The type of a value is fixed. So, multiple occurrences of a symbol denoting the same value (such as several uses of a formal parameter in a function body) must have identical type. L4Poly

  7. Systematic Type Derivation fun c f g x = f(g(x)) • Step1:Assign most general types to left-hand-side arguments and the (rhs) result. f : t1 g : t2 x : t3 f(g(x)) : t4 Thus, type of c is: c: t1 -> t2 -> t3 -> t4 L4Poly

  8. Step 2: Analyze and propagate type constraints • Application Rule If f x : t then x : t1 and f : t1 -> t, for some new t1. • Equality Rule If both x:t and x:t1 can be deduced for the value of a variable x, then t = t1. • Function Rule (t->u)=(t1->u1)iff(t=t1) /\ (u=u1) L4Poly

  9. f(g x): t4 AR (g x) : t5 f : t5 -> t4 AR x : t6 g: t6 -> t5 ER t1 = t5 -> t4 t2 = t6 -> t5 t3 = t6 Step 3: Overall deduced type c : (t5 -> t4) -> (t6 -> t5) -> (t6 -> t4) (unary function composition) L4Poly

  10. Example fun f x y = fst x + fst y given op + : int ->int -> int fst : ’a * ’b -> ’a Step 1: x: t1 y : t2 (fst_1 x + fst_2 y) : t3 The two instantiations of fst need not have the same type. fst_1 : u1 * u2 -> u1 fst_2 : v1 * v2 -> v1 f: t1 -> t2 -> t3 L4Poly

  11. Step 2: Applying rule for + (fst_1 x) : int (fst_2 y) : int t3 = int • Step 3: fst_1 : int*u2 -> int fst_2 : int*v2 -> int t1 = int * u2 t2 = int * v2 f: int * ’a -> int * ’b -> int L4Poly

  12. Example (fixed point) fun fix f = f (fix f) 1. Assume f : ’a -> ’b 2. From (fix f = f (…)) infer fix : (’a -> ’b) -> ’b 3. From ( ... = f (fix f)) infer fix : (’a -> ’b) -> ’a fix : ’a -> ’a -> ’a L4Poly

  13. Recursive Definition (curried function) fun f x y = f (f x) 0; f: (int -> ’a) -> int -> ’a fun f x y = f (f x) (f x y); f: (’a -> ’a) -> ’a -> ’a fun f f = f; (* identity function *) (* names of formals and functions come from disjoint namespaces *) fun f x y = f x; (* illegal *) fun f g = g f; (* illegal *) L4Poly

  14. Example (ill-typed definition) fun selfApply f = f f 1. f_1:t1 (f_2 f_3):t2 selfApply : t1 -> t2 2. f_3 : t3 f_2 : t3 -> t2 3. t1 = t3 = t3 -> t2 (unsatisfiable) (cf. val selfApply = I I) L4Poly

  15. Problematic Case fn x => (1, “a”); val it = fn : 'a -> int * string fn f => (f 1, f “a”); Type error “Least upper bound” of int and string does not exist, and the expression cannot be typed as ((’a->’b) ->’b*’b) because the following expression is not type correct. ( (fn f => (f 1, f “a”)) (Real.Math.sqrt) ); L4Poly

  16. (cont’d) fn (x,y) => (size x, length y); val it = fn : string * 'a list -> int * int fn z => (size z, length z); Type Error string and list cannot be unified to obtain ’a -> (int * int). Or else, it will conflict with type instantiation rule, compromising type safety. L4Poly

  17. Equivalence? (let val V = E in F end) =/= ((fn V => F) E) Even though both these expressions have the same behavior, the lambda abstraction is more restricted because it is type checked independently of the context of its use. In particular, the polymorphic type variable introduced in an abstraction must be treated differently from that introduced in a local definition. L4Poly

More Related