Plan PREVIOUSLY: unit, sequencing, let Type Systems TODAY: Winter Semester 2006 1. pairs, options, variants 2. recursion 3. state NEXT: exceptions? Week 8 NEXT: polymorphic (not so simple) typing December 6 December 6, 2006 - version 1.0 Pairs Evaluation rules for pairs t ::= ... terms {v 1 ,v 2 } . 1 − ( E-PairBeta1 ) → v 1 pair {t,t} first projection t.1 {v 1 ,v 2 } . 2 − → v 2 ( E-PairBeta2 ) second projection t.2 → t ′ t 1 − v ::= ... values 1 ( E-Proj1 ) → t ′ pair value t 1 .1 − 1 .1 {v,v} → t ′ T ::= ... types t 1 − 1 ( E-Proj2 ) product type T 1 × T 2 t 1 .2 − → t ′ 1 .2 → t ′ t 1 − 1 ( E-Pair1 ) → {t ′ {t 1 ,t 2 } − 1 ,t 2 } → t ′ t 2 − 2 ( E-Pair2 ) → {v 1 ,t ′ {v 1 ,t 2 } − 2 }
Typing rules for pairs Tuples t ::= ... terms Γ ⊢ t 1 : T 1 Γ ⊢ t 2 : T 2 i ∈ 1 .. n } tuple {t i ( T-Pair ) Γ ⊢ {t 1 ,t 2 } : T 1 × T 2 projection t.i v ::= ... values Γ ⊢ t 1 : T 11 × T 12 i ∈ 1 .. n } tuple value {v i ( T-Proj1 ) Γ ⊢ t 1 .1 : T 11 T ::= ... types i ∈ 1 .. n } tuple type {T i Γ ⊢ t 1 : T 11 × T 12 ( T-Proj2 ) Γ ⊢ t 1 .2 : T 12 Evaluation rules for tuples Typing rules for tuples for each i Γ ⊢ t i : T i {v i i ∈ 1 .. n }.j − → v j ( E-ProjTuple ) ( T-Tuple ) Γ ⊢ {t i i ∈ 1 .. n } : {T i i ∈ 1 .. n } → t ′ t 1 − 1 ( E-Proj ) Γ ⊢ t 1 : {T i i ∈ 1 .. n } → t ′ t 1 .i − 1 .i ( T-Proj ) Γ ⊢ t 1 .j : T j → t ′ t j − j ( E-Tuple ) {v i i ∈ 1 .. j − 1 ,t j ,t k k ∈ j + 1 .. n } − → {v i i ∈ 1 .. j − 1 ,t ′ j ,t k k ∈ j + 1 .. n }
Records Evaluation rules for records t ::= ... terms {l i =v i i ∈ 1 .. n }.l j − → v j ( E-ProjRcd ) i ∈ 1 .. n } record {l i =t i projection t.l → t ′ t 1 − v ::= ... values 1 ( E-Proj ) → t ′ i ∈ 1 .. n } record value t 1 .l − 1 .l {l i =v i T ::= ... types → t ′ t j − i ∈ 1 .. n } type of records {l i :T i j ( E-Rcd ) {l i =v i i ∈ 1 .. j − 1 ,l j =t j ,l k =t k k ∈ j + 1 .. n } − → {l i =v i i ∈ 1 .. j − 1 ,l j =t ′ j ,l k =t k k ∈ j + 1 .. n } Typing rules for records for each i Γ ⊢ t i : T i ( T-Rcd ) Γ ⊢ {l i =t i i ∈ 1 .. n } : {l i :T i i ∈ 1 .. n } Γ ⊢ t 1 : {l i :T i i ∈ 1 .. n } Sums and variants ( T-Proj ) Γ ⊢ t 1 .l j : T j
Sums – motivating example New syntactic forms t ::= ... terms PhysicalAddr = {firstlast:String, addr:String} inl t tagging (left) VirtualAddr = {name:String, email:String} inr t tagging (right) Addr = PhysicalAddr + VirtualAddr case t of inl x ⇒ t | inr x ⇒ t case inl “ PhysicalAddr → PhysicalAddr+VirtualAddr ” : inr “ VirtualAddr → PhysicalAddr+VirtualAddr ” : v ::= ... values inl v tagged value (left) getName = λ a:Addr. inr v tagged value (right) case a of inl x ⇒ x.firstlast T ::= ... types | inr y ⇒ y.name; T+T sum type T 1 +T 2 is a disjoint union of T 1 and T 2 (the tags inl and inr ensure disjointness) New evaluation rules → t ′ t − New typing rules Γ ⊢ t : T case (inl v 0 ) − → [ x 1 �→ v 0 ] t 1 ( E-CaseInl ) Γ ⊢ t 1 : T 1 ( T-Inl ) of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 Γ ⊢ inl t 1 : T 1 +T 2 → [ x 2 �→ v 0 ] t 2 ( E-CaseInr ) case (inr v 0 ) − Γ ⊢ t 1 : T 2 of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 ( T-Inr ) Γ ⊢ inr t 1 : T 1 +T 2 → t ′ t 0 − 0 ( E-Case ) Γ ⊢ t 0 : T 1 +T 2 case t 0 of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 → case t ′ − 0 of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 Γ , x 1 :T 1 ⊢ t 1 : T Γ , x 2 :T 2 ⊢ t 2 : T Γ ⊢ case t 0 of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 : T ( T-Case ) t 1 − → t ′ 1 ( E-Inl ) → inl t ′ inl t 1 − 1 t 1 − → t ′ 1 ( E-Inr ) → inr t ′ inr t 1 − 1
Sums and Uniqueness of Types New syntactic forms t ::= ... terms Problem: inl t as T tagging (left) If t has type T , then inl t has type T+U for every U . inr t as T tagging (right) I.e., we’ve lost uniqueness of types. v ::= ... values Possible solutions: inl v as T tagged value (left) ◮ “Infer” U as needed during typechecking inr v as T tagged value (right) ◮ Give constructors different names and only allow each name to appear in one sum type (requires generalization to “variants,” which we’ll see next) — OCaml’s solution Note that as T here is not the ascription operator that we saw ◮ Annotate each inl and inr with the intended sum type. before — i.e., not a separate syntactic form: in essence, there is an For simplicity, let’s choose the third. ascription “built into” every use of inl or inr . New typing rules Γ ⊢ t : T Evaluation rules ignore annotations: → t ′ t − Γ ⊢ t 1 : T 1 case (inl v 0 as T 0 ) ( T-Inl ) of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 ( E-CaseInl ) Γ ⊢ inl t 1 as T 1 +T 2 : T 1 +T 2 − → [ x 1 �→ v 0 ] t 1 Γ ⊢ t 1 : T 2 ( T-Inr ) case (inr v 0 as T 0 ) Γ ⊢ inr t 1 as T 1 +T 2 : T 1 +T 2 ( E-CaseInr ) of inl x 1 ⇒ t 1 | inr x 2 ⇒ t 2 → [ x 2 �→ v 0 ] t 2 − → t ′ t 1 − 1 ( E-Inl ) → inl t ′ inl t 1 as T 2 − 1 as T 2 → t ′ t 1 − 1 ( E-Inr ) inr t 1 as T 2 − → inr t ′ 1 as T 2
Variants New syntactic forms t ::= ... terms Just as we generalized binary products to labeled records, we can <l=t> as T tagging generalize binary sums to labeled variants . case t of <l i =x i > ⇒ t i i ∈ 1 .. n case T ::= ... types <l i :T i i ∈ 1 .. n > type of variants New evaluation rules → t ′ New typing rules Γ ⊢ t : T t − case (<l j =v j > as T) of <l i =x i > ⇒ t i i ∈ 1 .. n Γ ⊢ t j : T j ( E-CaseVariant ) i ∈ 1 .. n > ( T-Variant ) − → [ x j �→ v j ] t j Γ ⊢ <l j =t j > as <l i :T i i ∈ 1 .. n > : <l i :T i → t ′ t 0 − Γ ⊢ t 0 : <l i :T i i ∈ 1 .. n > 0 ( E-Case ) i ∈ 1 .. n for each i Γ , x i :T i ⊢ t i : T case t 0 of <l i =x i > ⇒ t i ( T-Case ) → case t ′ i ∈ 1 .. n − 0 of <l i =x i > ⇒ t i i ∈ 1 .. n : T Γ ⊢ case t 0 of <l i =x i > ⇒ t i → t ′ t i − i ( E-Variant ) → <l i =t ′ <l i =t i > as T − i > as T
Example Options Just like in OCaml... Addr = <physical:PhysicalAddr, virtual:VirtualAddr>; OptionalNat = <none:Unit, some:Nat>; a = <physical=pa> as Addr; Table = Nat → OptionalNat; getName = λ a:Addr. case a of emptyTable = λ n:Nat. <none=unit> as OptionalNat; <physical=x> ⇒ x.firstlast | <virtual=y> ⇒ y.name; extendTable = λ t:Table. λ m:Nat. λ v:Nat. λ n:Nat. if equal n m then <some=v> as OptionalNat else t n; x = case t(5) of <none=u> ⇒ 999 | <some=v> ⇒ v; Enumerations Weekday = <monday:Unit, tuesday:Unit, wednesday:Unit, thursday:Unit, friday:Unit>; nextBusinessDay = λ w:Weekday. case w of <monday=x> ⇒ <tuesday=unit> as Weekday | <tuesday=x> ⇒ <wednesday=unit> as Weekday | <wednesday=x> ⇒ <thursday=unit> as Weekday | <thursday=x> ⇒ <friday=unit> as Weekday | <friday=x> ⇒ <monday=unit> as Weekday;
Recommend
More recommend