Coercion Quantification Ningning Xie 1 Richard A. Eisenberg 2 22 - - PowerPoint PPT Presentation

coercion quantification
SMART_READER_LITE
LIVE PREVIEW

Coercion Quantification Ningning Xie 1 Richard A. Eisenberg 2 22 - - PowerPoint PPT Presentation

Coercion Quantification Ningning Xie 1 Richard A. Eisenberg 2 22 Sept. 2018 Haskell Implementors Workshop (HIW18) 1 The University of Hong Kong 2 Bryn Mawr College 1 Motivation Motivation Our long-term goal is to have Dependent Haskell


slide-1
SLIDE 1

Coercion Quantification

Ningning Xie 1 Richard A. Eisenberg 2 22 Sept. 2018

Haskell Implementor’s Workshop (HIW’18)

1The University of Hong Kong 2Bryn Mawr College

1

slide-2
SLIDE 2

Motivation

slide-3
SLIDE 3

Motivation

Our long-term goal is to have Dependent Haskell

2

slide-4
SLIDE 4

Motivation

Our long-term goal is to have Dependent Haskell The World of Haskell

2

slide-5
SLIDE 5

Motivation

Our long-term goal is to have Dependent Haskell The World of Haskell Dependent Haskell

2

slide-6
SLIDE 6

Motivation

Our long-term goal is to have Dependent Haskell The World of Haskell Dependent Haskell Dependent Core

2

slide-7
SLIDE 7

Motivation

Our long-term goal is to have Dependent Haskell The World of Haskell Dependent Haskell Dependent Core Homogeneous Equality

2

slide-8
SLIDE 8

Motivation

Our long-term goal is to have Dependent Haskell The World of Haskell Dependent Haskell Dependent Core Homogeneous Equality Coercion Quantification

2

slide-9
SLIDE 9

Outline

  • From Haskell to Coercion Quantification
  • Coercion Quantification
  • For Core Contributors: Theory and Implementation
  • For Haskell Users: Design Space in Source Haskell
  • Future Work

3

slide-10
SLIDE 10

From Haskell to Coercion Quantification

slide-11
SLIDE 11

From Haskell to Coercion Quantification

  • Why Dependent Types?

4

slide-12
SLIDE 12

Why Dependent Types?

We want dependent types...Oh, do we?

  • A language with dependent types may include references to

programs inside of types.

5

slide-13
SLIDE 13

Why Dependent Types?

We want dependent types...Oh, do we?

  • A language with dependent types may include references to

programs inside of types.

  • Length-indexed vectors

data Nat = Zero | Succ Nat data Vec :: Type → Nat → Type where Nil :: Vec a Zero Cons :: a → Vec a n → Vec a (Succ n)

5

slide-14
SLIDE 14

Why Dependent Types?

We want dependent types...Oh, do we?

  • A language with dependent types may include references to

programs inside of types.

  • Length-indexed vectors

data Nat = Zero | Succ Nat data Vec :: Type → Nat → Type where Nil :: Vec a Zero Cons :: a → Vec a n → Vec a (Succ n)

  • - vector of length 3

vec1 :: Vec Int (Succ (Succ (Succ Zero))) vec1 = Cons 1 (Cons 2 (Cons 3 Nil))

5

slide-15
SLIDE 15

Why Dependent Types?

We want dependent types...Oh, do we?

  • A language with dependent types may include references to

programs inside of types.

  • Length-indexed vectors

data Nat = Zero | Succ Nat data Vec :: Type → Nat → Type where Nil :: Vec a Zero Cons :: a → Vec a n → Vec a (Succ n)

  • - vector of length 3

vec1 :: Vec Int (Succ (Succ (Succ Zero))) vec1 = Cons 1 (Cons 2 (Cons 3 Nil))

  • - type error!

vec2 :: Vec Int (Succ (Succ Zero)) vec2 = Cons 1 (Cons 2 (Cons 3 Nil))

5

slide-16
SLIDE 16

Why Dependent Types?

  • - accepts only non-empty vector

vecHead :: Vec a (Succ n) → a vecHead (Cons x xs) = x

6

slide-17
SLIDE 17

Why Dependent Types?

  • - accepts only non-empty vector

vecHead :: Vec a (Succ n) → a vecHead (Cons x xs) = x

  • - type error!

headOfEmpty = vecHead Nil

6

slide-18
SLIDE 18

Why Dependent Types?

  • - accepts only non-empty vector

vecHead :: Vec a (Succ n) → a vecHead (Cons x xs) = x

  • - type error!

headOfEmpty = vecHead Nil

  • - addition in type-level

type family Plus (x::Nat) (y::Nat) :: Nat where Plus Zero y = y Plus (Succ x) y = Succ (Plus x y)

6

slide-19
SLIDE 19

Why Dependent Types?

  • - accepts only non-empty vector

vecHead :: Vec a (Succ n) → a vecHead (Cons x xs) = x

  • - type error!

headOfEmpty = vecHead Nil

  • - addition in type-level

type family Plus (x::Nat) (y::Nat) :: Nat where Plus Zero y = y Plus (Succ x) y = Succ (Plus x y)

  • - property of length is ensured in type-level

append :: Vec a n → Vec a m → Vec a (Plus n m) append Nil v = v append (Cons a v1) v2 = Cons a (append v1 v2)

6

slide-20
SLIDE 20

Why Dependent Types?

  • Dependent types help us eliminate erroneous programs
  • Type-level computation
  • Equivalence proofs
  • ...

7

slide-21
SLIDE 21

From Haskell to Coercion Quantification

  • Why Dependent Types?
  • Why Dependent Haskell?

8

slide-22
SLIDE 22

Why Dependent Haskell?

A set of language extensions for GHC that provides the ability to program as if the language had dependent types1

{-# LANGUAGE DataKinds, TypeFamilies, PolyKinds, TypeInType, GADTs, RankNTypes, TypeOperators, FunctionalDependencies, ScopedTypeVariables, TypeApplications, Template Haskell, UndecidableInstances, InstanceSigs, TypeSynonymInstances, KindSignatures, MultiParamTypeClasses, TypeFamilyDependencies, AllowAmbiguousTypes, FlexibleContexts ... #-}

1Adapted from Dependent Types in Haskell by Stephanie Weirich at

StrangeLoop’17

9

slide-23
SLIDE 23

Why Dependent Haskell?

  • There is no unified meta-theory for the extensions.

10

slide-24
SLIDE 24

Why Dependent Haskell?

  • There is no unified meta-theory for the extensions.
  • Duplications for term-level and type-level functions.
  • - term-level function

plus :: Nat → Nat → Nat plus Zero m = m plus (Succ n) m = Succ (plus n m)

10

slide-25
SLIDE 25

Why Dependent Haskell?

  • There is no unified meta-theory for the extensions.
  • Duplications for term-level and type-level functions.
  • - term-level function

plus :: Nat → Nat → Nat plus Zero m = m plus (Succ n) m = Succ (plus n m)

  • Restrictions:
  • All applications of a type family must be fully saturated with

respect to that arity;

  • Data families are not promoted;
  • ...

10

slide-26
SLIDE 26

Why Dependent Haskell?

  • There is no unified meta-theory for the extensions.
  • Duplications for term-level and type-level functions.
  • - term-level function

plus :: Nat → Nat → Nat plus Zero m = m plus (Succ n) m = Succ (plus n m)

  • Restrictions:
  • All applications of a type family must be fully saturated with

respect to that arity;

  • Data families are not promoted;
  • ...
  • Plan: to extend GHC with full-spectrum dependent types in a

way that is compatible with the current implementation, with the goal of simplifying and unifying many of GHC’s extensions (Eisenberg, 2016; Gundry, 2013; Weirich et al., 2017).

10

slide-27
SLIDE 27

From Haskell to Coercion Quantification

  • Why Dependent Types?
  • Why Dependent Haskell?
  • Why Dependent Core?

11

slide-28
SLIDE 28

Why Dependent Core?

Adding dependent types to GHC in one patch...

12

slide-29
SLIDE 29

Why Dependent Core?

Adding dependent types to GHC in one patch... is very difficult 2.

2High-level Dependency Graph from

https://ghc.haskell.org/trac/ghc/wiki/Commentary/ModuleStructure

12

slide-30
SLIDE 30

Why Dependent Core?

  • GHC incorporates several

compilation phases 3.

3Compiler Pipeline from

https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscPipe

13

slide-31
SLIDE 31

Why Dependent Core?

  • GHC incorporates several

compilation phases 3.

  • Dependent Core, as steps are

taken towards dependent Haskell (Weirich et al., 2017).

3Compiler Pipeline from

https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscPipe

13

slide-32
SLIDE 32

Why Dependent Core?

  • GHC incorporates several

compilation phases 3.

  • Dependent Core, as steps are

taken towards dependent Haskell (Weirich et al., 2017).

  • Some discussions can be found

in Haskell wiki4.

3Compiler Pipeline from

https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscPipe

4https://ghc.haskell.org/trac/ghc/wiki/DependentHaskell/Phase2

13

slide-33
SLIDE 33

From Haskell to Coercion Quantification

  • Why Dependent Types?
  • Why Dependent Haskell?
  • Why Dependent Core?
  • Why Homogeneous Equality?

14

slide-34
SLIDE 34

Why Homogeneous Equality?

  • Given an equality proposition a : A ∼ b : B
  • Homogeneous Equality: A and B are definitionally equivalent

types.

  • Heterogeneous Equality: A and B may be unrelated.

15

slide-35
SLIDE 35

Why Homogeneous Equality?

  • Given an equality proposition a : A ∼ b : B
  • Homogeneous Equality: A and B are definitionally equivalent

types.

  • Heterogeneous Equality: A and B may be unrelated.
  • A Specification for Dependent Types in Haskell (Weirich

et al., 2017). The most important change is that we show that the use

  • f homogeneous equality propositions is compatible with

explicit coercion proofs...by changing our treatment of equality propositions, we are able to simplify both the language semantics and the proofs of its metatheoretic properties with no cost to expressiveness...

15

slide-36
SLIDE 36

From Haskell to Coercion Quantification

  • Why Dependent Types?
  • Why Dependent Haskell?
  • Why Dependent Core?
  • Why Homogeneous Equality?
  • Why Coercion Quantification?

16

slide-37
SLIDE 37

Why Coercion Quantification?

Suppose we have homogeneous equalities A ∼# B in Core, then how can we define the kind-indexed GADTs? 5

  • - Source

data Rep :: ∀ k. k → Type where RepBool :: Rep Bool

  • - instantiate k to Type

RepMaybe :: Rep Maybe -- instantiate k to Type → Type

5Codes in Source Haskell are in black, and codes in Core are in blue.

17

slide-38
SLIDE 38

Why Coercion Quantification?

Suppose we have homogeneous equalities A ∼# B in Core, then how can we define the kind-indexed GADTs? 5

  • - Source

data Rep :: ∀ k. k → Type where RepBool :: Rep Bool

  • - instantiate k to Type

RepMaybe :: Rep Maybe -- instantiate k to Type → Type

  • - Core

Rep :: ∀ k. k → Type RepBool :: ∀ k (a :: k). (k ∼# Type) → (a ∼# Bool) -- ill-kinded → Rep k a RepMaybe :: ∀ k (a :: k). (k ∼# (Type → Type)) → (a ∼# Maybe) -- ill-kinded → Rep k a

5Codes in Source Haskell are in black, and codes in Core are in blue.

17

slide-39
SLIDE 39

Why Coercion Quantification?

Suppose we have homogeneous equalities A ∼# B in Core, then how can we define the kind-indexed GADTs? 5

  • - Source

data Rep :: ∀ k. k → Type where RepBool :: Rep Bool

  • - instantiate k to Type

RepMaybe :: Rep Maybe -- instantiate k to Type → Type

  • - Core

Rep :: ∀ k. k → Type RepBool :: ∀ k (a :: k). ∀ (cv :: k ∼# Type). -- a name for kind co ((a ⊲ cv) ∼# Bool) -- kind cast → Rep k a RepMaybe :: ∀ k (a :: k). ∀ (cv :: k ∼# (Type → Type)).--kind co ((a ⊲ cv) ∼# Maybe) -- kind cast → Rep k a

5Codes in Source Haskell are in black, and codes in Core are in blue.

17

slide-40
SLIDE 40

Coercion Quantification

slide-41
SLIDE 41

Coercion Quantification

A quantification over a coercion variable.

18

slide-42
SLIDE 42

Coercion Quantification

A quantification over a coercion variable.

  • Forall-type over coercion variable.

RepBool :: ∀ k (a :: k). ∀ (cv :: k ∼# Type). -- kind coercion ((a ⊲ cv) ∼# Bool) -- cast → Rep k a

18

slide-43
SLIDE 43

Coercion Quantification

A quantification over a coercion variable.

  • Forall-type over coercion variable.

RepBool :: ∀ k (a :: k). ∀ (cv :: k ∼# Type). -- kind coercion ((a ⊲ cv) ∼# Bool) -- cast → Rep k a

  • Forall-coercion over coercion variable.

∀ c: c1. c2 -- a coercion between two

  • - (Forall-types over coercion variable)

:: ∀ (co1:: k1 ∼# k2). A ∼# ∀ (co2::k3 ∼# k4). B

18

slide-44
SLIDE 44

Coercion Quantification: Theory and Implementation

Theory

  • Typing rules: roles, NthCo, InstCo; optimizations; visibility

rules; ...

19

slide-45
SLIDE 45

Coercion Quantification: Theory and Implementation

Theory

  • Typing rules: roles, NthCo, InstCo; optimizations; visibility

rules; ... Γ ⊢ γ1 : (t1 ∼r t2) ∼N (t3 ∼r t4) Γ, c : t1 ∼r t2 ⊢ γ2 : t5 ∼r2 t6 η1 = Nth r 2 (downgradeRole r N γ1) :: t1 ∼r t3 η2 = Nth r 3 (downgradeRole r N γ1) :: t2 ∼r t4 Γ ⊢ ∀c : γ1.γ2 :: (∀c : t1 ∼ t2.t5) ∼r2 (∀c : t3 ∼ t4.t6[c → η1; c; η2])

19

slide-46
SLIDE 46

Coercion Quantification: Theory and Implementation

Practice

  • Merged patch: https://phabricator.haskell.org/D5054
  • Both ForAllTy and ForAllCo can quantify over coercion

variables, but only in Core.

  • All relevant functions are updated accordingly.

20

slide-47
SLIDE 47

Coercion Quantification: Theory and Implementation

Example: compiler/basicTypes/DataCon.hs6

data DataCon = MkData { ... dcUnivTyVars :: [TyVar] dcExTyVars :: [TyVar] dcUserTyVarBinders :: [TyVarBinder] ... }

  • - old invariant : tyvars in dcUserTyVarBinders =

dcUnivTyVars ‘union‘ dcExTyVars

6Simplified for presentation.

21

slide-48
SLIDE 48

Coercion Quantification: Theory and Implementation

Example: compiler/basicTypes/DataCon.hs6

data DataCon = MkData { ... dcUnivTyVars :: [TyVar] dcExTyVars :: [TyVar] dcUserTyVarBinders :: [TyVarBinder] ... }

  • - old invariant : tyvars in dcUserTyVarBinders =

dcUnivTyVars ‘union‘ dcExTyVars data DataCon = MkData { ... dcUnivTyVars :: [TyVar] dcExTyCoVars :: [TyCoVar] -- covars allowed dcUserTyVarBinders :: [TyVarBinder] ... }

  • - new invariant : tyvars in dcUserTyVarBinders =

dcUnivTyVars ‘union‘ (tyvars in dcExTyCoVars)

6Simplified for presentation.

21

slide-49
SLIDE 49

Coercion Quantification: Design Space in Source Haskell

  • So far, the user experience with Haskell should not be

changed at all.

22

slide-50
SLIDE 50

Coercion Quantification: Design Space in Source Haskell

  • So far, the user experience with Haskell should not be

changed at all.

  • Question for Haskellers: do you want the compiler to accept

the type of fun?

data SameKind :: k → k → * fun :: ∀ k1 k2 (a::k1) (b::k2). (k1 ∼ k2) ⇒ SameKind a b

22

slide-51
SLIDE 51

Coercion Quantification: Design Space in Source Haskell

  • So far, the user experience with Haskell should not be

changed at all.

  • Question for Haskellers: do you want the compiler to accept

the type of fun?

  • - rejected!

data SameKind :: k → k → * fun :: ∀ k1 k2 (a::k1) (b::k2). (k1 ∼ k2) ⇒ SameKind a b

22

slide-52
SLIDE 52

Coercion Quantification: Design Space in Source Haskell

  • So far, the user experience with Haskell should not be

changed at all.

  • Question for Haskellers: do you want the compiler to accept

the type of fun?

  • - rejected!

data SameKind :: k → k → * fun :: ∀ k1 k2 (a::k1) (b::k2). (k1 ∼ k2) ⇒ SameKind a b

If the solver is smart enough (which implies non-trivial extensions), it should accept the program and produce

  • - in Core

data SameKind :: k → k → * fun :: ∀ k1 k2 (a:k1) (b:k2). (co :: k1 ∼# k2). -- generate a name SameKind (a ⊲ co) b -- insert a cast

22

slide-53
SLIDE 53

Future Work

slide-54
SLIDE 54

Future Work

  • Implementation of homogeneous equality in Core.
  • Dependent Core: unified syntax for terms/types/kinds,

elaboration, etc.

  • Dependent Source Haskell.

23

slide-55
SLIDE 55

References

Richard A. Eisenberg. 2016. Dependent Types in Haskell: Theory and Practice. PhD Dissertation. University of Pennsylvania. Adam Michael Gundry. 2013. Type Inference, Haskell and Dependent Types. PhD Dissertation. University of Strathclyde. Stephanie Weirich, Antoine Voizard, Pedro Henrique Avezedo de Amorim, and Richard A Eisenberg. 2017. A Specification for Dependent Types in Haskell. Proceedings of the ACM on Programming Languages 1, ICFP (2017), 31.

24

slide-56
SLIDE 56

Acknowledgments

Summer of Haskell

25

slide-57
SLIDE 57

Coercion Quantification

Ningning Xie 1 Richard A. Eisenberg 2 22 Sept. 2018

Haskell Implementor’s Workshop (HIW’18)

1The University of Hong Kong 2Bryn Mawr College

26

slide-58
SLIDE 58

Backup Slides

26

slide-59
SLIDE 59

Why Haskell?

Why Haskell? Why not any existing dependently typed language? [Eisenberg, 2016]

  • Haskell is a general purpose functional programming language.
  • Backward-compatible type inference.
  • No termination or totality checking.

27

slide-60
SLIDE 60

Different Equalities

Note [The equality types story] in compiler/prelude/TysPrim.hs

  • (∼#) :: ∀ k1 k2. k1 → k2 → #
  • The Type Of Equality in GHC. This type is used in the solver

for recording equality constraints.

  • We want this to be homogeneous.
  • (∼∼) :: ∀ k1 k2. k1 → k2 → Constraint
  • Defined as if

class a ∼# b ⇒ a ∼∼ b instance a ∼# b ⇒ a ∼∼ b

  • We want this to keep heterogeneous.

28

slide-61
SLIDE 61

Strongly Typed STLC

  • De Bruijn index

29

slide-62
SLIDE 62

Strongly Typed STLC

  • De Bruijn index
  • - type: unit, or arrow

data Typ = U | Typ :→ Typ infixr 0 :→

29

slide-63
SLIDE 63

Strongly Typed STLC

  • De Bruijn index
  • - type: unit, or arrow

data Typ = U | Typ :→ Typ infixr 0 :→

  • - context is a list of types, e.g. [U, U → U, U]

29

slide-64
SLIDE 64

Strongly Typed STLC

  • De Bruijn index
  • - type: unit, or arrow

data Typ = U | Typ :→ Typ infixr 0 :→

  • - context is a list of types, e.g. [U, U → U, U]
  • - variable in context

data Member :: a → [a] → * where First :: ∀ elm ls . Member elm (elm:ls) Next :: ∀ elm ls x . Member elm ls → Member elm (x:ls)

29

slide-65
SLIDE 65

Strongly Typed STLC

  • De Bruijn index
  • - type: unit, or arrow

data Typ = U | Typ :→ Typ infixr 0 :→

  • - context is a list of types, e.g. [U, U → U, U]
  • - variable in context

data Member :: a → [a] → * where First :: ∀ elm ls . Member elm (elm:ls) Next :: ∀ elm ls x . Member elm ls → Member elm (x:ls) test1 :: Member Int ’[Int, Bool] test1 = First test2 :: Member Bool ’[Int, Bool] test2 = Next First

  • - type error!
  • - test3 :: Member Int ’[Int, Bool]
  • - test3 = Next First

29

slide-66
SLIDE 66

Strongly Typed STLC

  • - context [Typ], expr has type Typ

data Expr :: [Typ] → Typ → * where Unit :: ∀ ts. Expr ts U Var :: ∀ ts t. Member t ts → Expr ts t Abs :: ∀ ts dom ran. Expr (dom:ts) ran → Expr ts (dom :→ ran) App :: ∀ ts dom ran. Expr ts (dom :→ ran) → Expr ts dom → Expr ts ran

30

slide-67
SLIDE 67

Strongly Typed STLC

  • - context [Typ], expr has type Typ

data Expr :: [Typ] → Typ → * where Unit :: ∀ ts. Expr ts U Var :: ∀ ts t. Member t ts → Expr ts t Abs :: ∀ ts dom ran. Expr (dom:ts) ran → Expr ts (dom :→ ran) App :: ∀ ts dom ran. Expr ts (dom :→ ran) → Expr ts dom → Expr ts ran

  • - \x. \y. x

fst’ :: Expr ’[] (a :→ b :→ a) fst’ = Abs (Abs (Var (Next First))) {- ^

  • |

^ | |

  • }

30

slide-68
SLIDE 68

Strongly Typed STLC

  • - context [Typ], expr has type Typ

data Expr :: [Typ] → Typ → * where Unit :: ∀ ts. Expr ts U Var :: ∀ ts t. Member t ts → Expr ts t Abs :: ∀ ts dom ran. Expr (dom:ts) ran → Expr ts (dom :→ ran) App :: ∀ ts dom ran. Expr ts (dom :→ ran) → Expr ts dom → Expr ts ran

  • - \x. \y. x

fst’’ :: Expr ’[] (a :→ b :→ b) -- ill-typed! fst’’ = Abs (Abs (Var (Next First))) {- ^

  • |

^ | |

  • }

30