principal type inference with subtyping
play

Principal type inference with subtyping Stephen Dolan and Alan - PowerPoint PPT Presentation

Principal type inference with subtyping Stephen Dolan and Alan Mycroft April 21, 2016 Computer Laboratory University of Cambridge select select p v d = if ( p v ) then v else d 2 select select p v d = if ( p v ) then v else d ML : . (


  1. Principal type inference with subtyping Stephen Dolan and Alan Mycroft April 21, 2016 Computer Laboratory University of Cambridge

  2. select select p v d = if ( p v ) then v else d 2

  3. select select p v d = if ( p v ) then v else d ML : ∀ α. ( α → bool) → α → α → α 2

  4. select select p v d = if ( p v ) then v else d ML : ∀ α. ( α → bool) → α → α → α v d argument to p result 2

  5. select select p v d = if ( p v ) then v else d ML : ∀ α. ( α → bool) → α → α → α v d argument to p result MLsub : ∀ α. ( α → bool) → α → β → ( α ⊔ β ) 2

  6. Defining types

  7. Extensibility When I add more types, no programs should break. 4

  8. Constructing types syntactically Types: τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } 5

  9. Constructing types syntactically Types with subtyping: τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } τ ′ τ 2 ≤ τ ′ 1 ≤ τ 1 2 τ 1 → τ 2 ≤ τ ′ 1 → τ ′ bool ≤ bool 2 { ℓ 1 : τ 1 , . . . , ℓ n : τ n , . . . } ≤ { ℓ 1 : τ 1 , . . . ℓ n : τ n } τ 1 ≤ τ ′ τ n ≤ τ ′ . . . 1 n { ℓ 1 : τ 1 , . . . , ℓ n : τ n } ≤ { ℓ 1 : τ ′ 1 , . . . , ℓ n : τ ′ n } 5

  10. Constructing types syntactically Types with subtyping, least and greatest types: τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } | ⊥ | ⊤ τ ′ τ 2 ≤ τ ′ 1 ≤ τ 1 2 τ 1 → τ 2 ≤ τ ′ 1 → τ ′ bool ≤ bool 2 { ℓ 1 : τ 1 , . . . , ℓ n : τ n , . . . } ≤ { ℓ 1 : τ 1 , . . . ℓ n : τ n } τ 1 ≤ τ ′ τ n ≤ τ ′ . . . 1 n { ℓ 1 : τ 1 , . . . , ℓ n : τ n } ≤ { ℓ 1 : τ ′ 1 , . . . , ℓ n : τ ′ n } ⊤ ≤ τ τ ≤ ⊤ 5

  11. Constructing types syntactically Types with lattice subtyping: τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } | ⊥ | ⊤ τ ′ τ 2 ≤ τ ′ 1 ≤ τ 1 2 τ 1 → τ 2 ≤ τ ′ 1 → τ ′ bool ≤ bool 2 { ℓ 1 : τ 1 , . . . , ℓ n : τ n , . . . } ≤ { ℓ 1 : τ 1 , . . . ℓ n : τ n } τ 1 ≤ τ ′ τ n ≤ τ ′ . . . 1 n { ℓ 1 : τ 1 , . . . , ℓ n : τ n } ≤ { ℓ 1 : τ ′ 1 , . . . , ℓ n : τ ′ n } ⊤ ≤ τ τ ≤ ⊤ 5

  12. What’s going on here? F ( A ) = Bool( A ) + Func( A ) + Rec( A ) Bool( A ) = bool Func( A ) = A × A Rec( A ) = L ⇀ A Take the initial algebra of F : Set → Set 6

  13. What’s going on here? F ( A ) = Bool( A ) + Func( A ) + Rec( A ) Bool( A ) = bool Func( A ) = A − × A Rec( A ) = L ⇀ A Take the initial algebra of F : Pos → Pos . 6

  14. What’s going on here? F ( A ) = Bool( A ) + Func( A ) + Rec( A ) Bool( A ) = (bool) ⊤ ⊥ Func( A ) = ( A − × A ) ⊤ ⊥ Rec( A ) = ( L ⇀ A ) ⊤ ⊥ Take the initial algebra of F : Pos ⊤ ⊥ → Pos ⊤ ⊥ . 6

  15. What’s going on here? F ( A ) = Bool( A ) + Func( A ) + Rec( A ) Bool( A ) = (bool) ⊤ ⊥ Func( A ) = ( A − × A ) ⊤ ⊥ Rec( A ) = ( L ⇀ A ) ⊤ ⊥ Take a lattice of types, forget that it’s a lattice, apply F : Pos ⊤ ⊥ → Pos ⊤ ⊥ , and notice that the result happens to be a lattice. 6

  16. What’s going on here? F ( A ) = Bool( A ) + Func( A ) + Rec( A ) Bool( A ) = (bool) ⊤ ⊥ Func( A ) = ( A − × A ) ⊤ ⊥ Rec( A ) = ( L ⇀ A ) ⊤ ⊥ Take the initial algebra of F : Lat → Lat . 6

  17. Coproducts τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } The | should be the coproduct. Not always union! 7

  18. Coproducts τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } The | should be the coproduct. Not always union! We get some new types: ( τ → τ ) ⊓ { foo : τ } 7

  19. Coproducts τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } The | should be the coproduct. Not always union! We get some new types: ( τ → τ ) ⊓ { foo : τ } ≤ bool 7

  20. Type variables How about type variables as metavariables ? 8

  21. Type variables How about type variables as metavariables ? Pottier’s tricky example: τ = ⊥ | τ → τ | ⊤ ( ⊥ → ⊤ ) → ⊥ ≤ ( α → ⊥ ) ⊔ α This is true, by case analysis . . . 8

  22. Type variables How about type variables as metavariables ? Pottier’s tricky example: τ = ⊥ | τ → τ | ⊤ ( ⊥ → ⊤ ) → ⊥ ≤ ( α → ⊥ ) ⊔ α This is true, by case analysis . . . until we extend the type system α = ( ⊤ ◦ ◦ → ⊥ ) → ⊥ 8

  23. Type variables How about type variables as metavariables ? Pottier’s tricky example: τ = ⊥ | τ → τ | ⊤ ( ⊥ → ⊤ ) → ⊥ ≤ ( α → ⊥ ) ⊔ α This is true, by case analysis . . . until we extend the type system α = ( ⊤ ◦ ◦ → ⊥ ) → ⊥ We need type variables as a free algebra . Syntactically, add them as opaque indeterminates: τ ::= bool | τ 1 → τ 2 | { ℓ 1 : τ 1 , . . . , ℓ n : τ n } | α 8

  24. Inferring types

  25. Polarity We have lots of types, but they’re not all useful all the time. τ 1 ⊔ τ 2 describes an output that may be τ 1 or may be τ 2 . τ 1 ⊓ τ 2 describes an input that must be τ 1 and must be τ 2 10

  26. Polarity We have lots of types, but they’re not all useful all the time. τ 1 ⊔ τ 2 describes an output that may be τ 1 or may be τ 2 . τ 1 ⊓ τ 2 describes an input that must be τ 1 and must be τ 2 Use positive types τ + for outputs, and negative types τ − for inputs: τ + ::= α | τ + ⊔ τ + | ⊥ | unit | τ − → τ + τ − ::= α | τ − ⊓ τ − | ⊤ | unit | τ + → τ − 10

  27. When does ML unify? Two inputs : introduce ⊓ Two outputs : introduce ⊔ Output used as an input : constraint τ + ≤ τ − 11

  28. When does ML unify? Two inputs : introduce ⊓ Two outputs : introduce ⊔ Output used as an input : constraint τ + ≤ τ − Handling ⊔ and ⊓ is easy, thanks to polarity: τ 1 ⊔ τ 2 ≤ τ 3 iff τ 1 ≤ τ 3 , τ 2 ≤ τ 3 τ 1 ≤ τ 2 ⊓ τ 3 iff τ 1 ≤ τ 2 , τ 1 ≤ τ 3 11

  29. Atomic constraints How do we get rid of α ≤ τ − or τ + ≤ α ? Not substitution! 12

  30. Atomic constraints How do we get rid of α ≤ τ − or τ + ≤ α ? Not substitution! ∀ � = Λ 12

  31. Atomic constraints How do we get rid of α ≤ τ − or τ + ≤ α ? Not substitution! ∀ � = Λ ML’s ∀ is more like a set comprehension. These are the same: ∀ α ∀ β. α → β → α ∀ β ∀ α. α → β → α because these are the same { α → β → α | α, β types } { α → β → α | β, α types } 12

  32. Preserving the set of instances It’s easy to remove constraints from set comprehensions: 13

  33. Preserving the set of instances It’s easy to remove constraints from set comprehensions: { n 2 + 17 | n ∈ N , n ≥ 5 } 13

  34. Preserving the set of instances It’s easy to remove constraints from set comprehensions: { n 2 + 17 | n ∈ N , n ≥ 5 } = { max( n , 5) 2 + 17 | n ∈ N } 13

  35. Preserving the set of instances It’s easy to remove constraints from set comprehensions: { n 2 + 17 | n ∈ N , n ≥ 5 } = { max( n , 5) 2 + 17 | n ∈ N } Thinking of type schemes as set comprehensions, we can do the same: α → α | α ≤ { isgood : bool } 13

  36. Preserving the set of instances It’s easy to remove constraints from set comprehensions: { n 2 + 17 | n ∈ N , n ≥ 5 } = { max( n , 5) 2 + 17 | n ∈ N } Thinking of type schemes as set comprehensions, we can do the same: α → α | α ≤ { isgood : bool } = ( α ⊓ { isgood : bool } ) → ( α ⊓ { isgood : bool } ) 13

  37. Preserving the set of instances It’s easy to remove constraints from set comprehensions: { n 2 + 17 | n ∈ N , n ≥ 5 } = { max( n , 5) 2 + 17 | n ∈ N } Thinking of type schemes as set comprehensions, we can do the same: α → α | α ≤ { isgood : bool } = ( α ⊓ { isgood : bool } ) → ( α ⊓ { isgood : bool } ) = ( α ⊓ { isgood : bool } ) → α 13

  38. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] 14

  39. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] list[ { isgood : bool }⊓ α ] → list[ α ] ≤ list[ { isgood : bool , x : int } ] → β 14

  40. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] list[ α ] ≤ β list[ { isgood : bool , x : int } ] ≤ list[ { isgood : bool } ⊓ α ] 14

  41. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] list[ α ] ≤ β { isgood : bool , x : int } ≤ { isgood : bool } ⊓ α 14

  42. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] list[ α ] ≤ β { isgood : bool , x : int } ≤ { isgood : bool } { isgood : bool , x : int } ≤ α 14

  43. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] list[ α ] ≤ β { isgood : bool , x : int } ≤ α 14

  44. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] β + �→ β ⊔ list[ α ] α + �→ α ⊔ { isgood : bool , x : int } 14

  45. Example filter good : list[ { isgood : bool } ⊓ α ] → list[ α ] things : list[ { isgood : bool , x : int } ] β ⊔ list[ α ⊔ { isgood : bool , x : int } ] 14

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend