Composing and Decomposing Data Types A Closed Type Families - - PowerPoint PPT Presentation

composing and decomposing data types
SMART_READER_LITE
LIVE PREVIEW

Composing and Decomposing Data Types A Closed Type Families - - PowerPoint PPT Presentation

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e Faculty of Science Composing and Decomposing Data Types A Closed Type Families Implementation of Data Types ` a la Carte Patrick Bahr


slide-1
SLIDE 1

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Faculty of Science

Composing and Decomposing Data Types

A Closed Type Families Implementation

  • f Data Types `

a la Carte Patrick Bahr

University of Copenhagen, Department of Computer Science paba@di.ku.dk

10th ACM SIGPLAN Workshop on Generic Programming, 31st August, 2014 Slide 1

slide-2
SLIDE 2

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Introduction

Experimenting with Closed Type Families

  • What can we do with them?
  • How do they compare to type classes?
  • How do they interact with type classes?

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 2

slide-3
SLIDE 3

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Introduction

Experimenting with Closed Type Families

  • What can we do with them?
  • How do they compare to type classes?
  • How do they interact with type classes?

Application: Data Types ` a la Carte

Specifically: the subtyping constraint : ≺:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 2

slide-4
SLIDE 4

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Introduction

Experimenting with Closed Type Families

  • What can we do with them?
  • How do they compare to type classes?
  • How do they interact with type classes?

Application: Data Types ` a la Carte

Specifically: the subtyping constraint : ≺:

  • Can we get rid of some of the restrictions?
  • Can we improve error messages?
  • What price do we have to pay?

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 2

slide-5
SLIDE 5

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-6
SLIDE 6

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-7
SLIDE 7

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-8
SLIDE 8

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith data Fix f = In (f (Fix f ))

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-9
SLIDE 9

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-10
SLIDE 10

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith Functors can be combined by coproduct construction :+:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-11
SLIDE 11

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith Functors can be combined by coproduct construction :+: data Mul a = Mul a a type Exp′ = Fix (Arith :+: Mul)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-12
SLIDE 12

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte [Swierstra 2008]

Idea: Decompose data types into two-level types:

Recursive data type

data Exp = Val Int | Add Exp Exp = ⇒

Fixpoint of functor

data Arith a = Val Int | Add a a type Exp = Fix Arith Functors can be combined by coproduct construction :+: data (f :+: g) a = Inl (f a) | Inr (g a) data Mul a = Mul a a type Exp′ = Fix (Arith :+: Mul)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 3

slide-13
SLIDE 13

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte (cont.)

Subtyping constraint : ≺:

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 4

slide-14
SLIDE 14

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte (cont.)

Subtyping constraint : ≺:

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) e.g. Mul : ≺: Arith :+: Mul

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 4

slide-15
SLIDE 15

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte (cont.)

Subtyping constraint : ≺:

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) e.g. Mul : ≺: Arith :+: Mul

Example: smart constructors

add :: (Arith : ≺: f ) ⇒ Fix f → Fix f → Fix f add x y = In (inj (Add x y))

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 4

slide-16
SLIDE 16

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Data Types ` a la Carte (cont.)

Subtyping constraint : ≺:

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) e.g. Mul : ≺: Arith :+: Mul

Example: smart constructors

add :: (Arith : ≺: f ) ⇒ Fix f → Fix f → Fix f add x y = In (inj (Add x y)) exp :: Fix (Arith :+: Mul) exp = val 1 ‘add‘ (val 2 ‘mul‘ val 3)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 4

slide-17
SLIDE 17

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance (f : ≺: f1) ⇒ f : ≺: (f1 :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-18
SLIDE 18

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-19
SLIDE 19

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:
  • Left-hand side is not inspected
  • Ambiguity

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-20
SLIDE 20

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:

A : ≺: A :+: (B :+: C)

  • Left-hand side is not inspected
  • Ambiguity

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-21
SLIDE 21

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:

A : ≺: (A :+: B) :+: C

  • Left-hand side is not inspected
  • Ambiguity

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-22
SLIDE 22

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:

A : ≺: (A :+: B) :+: C

  • Left-hand side is not inspected

A :+: B : ≺: (A :+: B) :+: C

  • Ambiguity

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-23
SLIDE 23

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:

A : ≺: (A :+: B) :+: C

  • Left-hand side is not inspected

A :+: B : ≺: A :+: (B :+: C)

  • Ambiguity

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-24
SLIDE 24

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Limitations of : ≺:

Definition of : ≺:

instance f : ≺: f where . . . instance f : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • Asymmetric treatment of :+:

A : ≺: (A :+: B) :+: C

  • Left-hand side is not inspected

A :+: B : ≺: A :+: (B :+: C)

  • Ambiguity

A : ≺: A :+: (A :+: B)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 5

slide-25
SLIDE 25

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Contributions We re-implemented : ≺: such that:

  • Subtyping behaves as intuitively expected*
  • Ambiguous subtyping is avoided
  • We can express isomorphism :≃:

*terms and conditions may apply

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 6

slide-26
SLIDE 26

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-27
SLIDE 27

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-28
SLIDE 28

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-29
SLIDE 29

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-30
SLIDE 30

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected: A : ≺: A :+: A :+: C A :+: A : ≺: A :+: B

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-31
SLIDE 31

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected: A : ≺: A :+: A :+: C A :+: A : ≺: A :+: B injection not unique!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-32
SLIDE 32

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected: A : ≺: A :+: A :+: C A :+: A : ≺: A :+: B injection not unique!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-33
SLIDE 33

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected: A : ≺: A :+: A :+: C A :+: A : ≺: A :+: B injection not unique! “injection” not injective!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-34
SLIDE 34

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ ∃ unique injection from f to g C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected: A : ≺: A :+: A :+: C A :+: A : ≺: A :+: B injection not unique! “injection” not injective!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 7

slide-35
SLIDE 35

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ ∃ unique bijection from f to g

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 8

slide-36
SLIDE 36

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ ∃ unique bijection from f to g Easy to implement: f :≃: g = (f : ≺: g, g : ≺: f )

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 8

slide-37
SLIDE 37

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ ∃ unique bijection from f to g Easy to implement: f :≃: g = (f : ≺: g, g : ≺: f )

Use case: improved projection function

The type of the projection function is unsatisfying: prj :: (f : ≺: g) ⇒ g a → Maybe (f a)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 8

slide-38
SLIDE 38

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ ∃ unique bijection from f to g Easy to implement: f :≃: g = (f : ≺: g, g : ≺: f )

Use case: improved projection function

The type of the projection function is unsatisfying: prj :: (f : ≺: g) ⇒ g a → Maybe (f a) With :≃: we can do better: split :: (g :≃: f :+: r) ⇒ g a → Either (f a) (r a)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 8

slide-39
SLIDE 39

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ ∃ unique bijection from f to g Easy to implement: f :≃: g = (f : ≺: g, g : ≺: f )

Use case: improved projection function

The type of the projection function is unsatisfying: prj :: (f : ≺: g) ⇒ g a → Maybe (f a) With :≃: we can do better: split :: (g :≃: f :+: r) ⇒ g a → (f a → b) → (r a → b) → b

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 8

slide-40
SLIDE 40

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Implementation of : ≺:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 9

slide-41
SLIDE 41

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • check whether f :

≺: g

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-42
SLIDE 42

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • check whether f :

≺: g Derive implementation of inj and prj: ???

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-43
SLIDE 43

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • produce proof object p for f :

≺: g Derive implementation of inj and prj:

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-44
SLIDE 44

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • produce proof object p for f :

≺: g Derive implementation of inj and prj:

  • also use a type class
  • But: use proof object as oracle in instance declarations

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-45
SLIDE 45

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • produce proof object p for f :

≺: g Derive implementation of inj and prj:

  • also use a type class
  • But: use proof object as oracle in instance declarations

No singleton types. This all happens at compile time!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-46
SLIDE 46

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • produce proof object p for f :

≺ ≺: g Derive implementation of inj and prj:

  • also use a type class
  • But: use proof object as oracle in instance declarations

No singleton types. This all happens at compile time!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-47
SLIDE 47

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Idea

Type-level function Embed:

  • take two signatures f , g as arguments
  • produce proof object p for f :

≺ ≺: g

  • check whether p also proves f :

≺: g Derive implementation of inj and prj:

  • also use a type class
  • But: use proof object as oracle in instance declarations

No singleton types. This all happens at compile time!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 10

slide-48
SLIDE 48

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-49
SLIDE 49

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-50
SLIDE 50

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f p : f : ≺ ≺: g1 Left p : f : ≺ ≺: g1 :+: g2 p : f : ≺ ≺: g2 Right p : f : ≺ ≺: g1 :+: g2

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-51
SLIDE 51

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f p : f : ≺ ≺: g1 Left p : f : ≺ ≺: g1 :+: g2 p : f : ≺ ≺: g2 Right p : f : ≺ ≺: g1 :+: g2 p1 : f1 : ≺ ≺: g p2 : f2 : ≺ ≺: g Sum p1 p2 : f1 :+: f2 : ≺ ≺: g

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-52
SLIDE 52

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f p : f : ≺ ≺: g1 Left p : f : ≺ ≺: g1 :+: g2 p : f : ≺ ≺: g2 Right p : f : ≺ ≺: g1 :+: g2 p1 : f1 : ≺ ≺: g p2 : f2 : ≺ ≺: g Sum p1 p2 : f1 :+: f2 : ≺ ≺: g kind

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-53
SLIDE 53

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f p : f : ≺ ≺: g1 Left p : f : ≺ ≺: g1 :+: g2 p : f : ≺ ≺: g2 Right p : f : ≺ ≺: g1 :+: g2 p1 : f1 : ≺ ≺: g p2 : f2 : ≺ ≺: g Sum p1 p2 : f1 :+: f2 : ≺ ≺: g kind type

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-54
SLIDE 54

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Proof Objects

Definition

data Prf = Refl | Left Prf | Right Prf | Sum Prf Prf Refl : f : ≺ ≺: f p : f : ≺ ≺: g1 Left p : f : ≺ ≺: g1 :+: g2 p : f : ≺ ≺: g2 Right p : f : ≺ ≺: g1 :+: g2 p1 : f1 : ≺ ≺: g p2 : f2 : ≺ ≺: g Sum p1 p2 : f1 :+: f2 : ≺ ≺: g kind type type constructor

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 11

slide-55
SLIDE 55

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Construct Proof Objects

data Emb = Found Prf | NotFound | Ambiguous

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 12

slide-56
SLIDE 56

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Construct Proof Objects

data Emb = Found Prf | NotFound | Ambiguous type family Embed (f :: ∗ → ∗) (g :: ∗ → ∗) :: Emb where

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 12

slide-57
SLIDE 57

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Construct Proof Objects

data Emb = Found Prf | NotFound | Ambiguous type family Embed (f :: ∗ → ∗) (g :: ∗ → ∗) :: Emb where Embed f f = Found Refl Embed (f1 :+: f2) g = Sum′ (Embed f1 g) (Embed f2 g) Embed f (g1 :+: g2) = Choose (Embed f g1) (Embed f g2) Embed f g = NotFound

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 12

slide-58
SLIDE 58

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Construct Proof Objects

data Emb = Found Prf | NotFound | Ambiguous type family Embed (f :: ∗ → ∗) (g :: ∗ → ∗) :: Emb where Embed f f = Found Refl Embed (f1 :+: f2) g = Sum′ (Embed f1 g) (Embed f2 g) Embed f (g1 :+: g2) = Choose (Embed f g1) (Embed f g2) Embed f g = NotFound type family Choose (e1 :: Emb) (e2 :: Emb) :: Emb where Choose (Found p1) (Found p2) = Ambiguous Choose Ambiguous e2 = Ambiguous Choose e1 Ambiguous = Ambiguous Choose (Found p1) e2 = Found (Left p1) Choose e1 (Found p2) = Found (Right p2) Choose NotFound NotFound = NotFound

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 12

slide-59
SLIDE 59

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Post-Processing

This is almost what we want.

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 13

slide-60
SLIDE 60

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Post-Processing

This is almost what we want.

  • We avoid ambiguity on the right-hand side:

A : ≺: A :+: A :+: C

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 13

slide-61
SLIDE 61

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Post-Processing

This is almost what we want.

  • We avoid ambiguity on the right-hand side:

A : ≺: A :+: A :+: C

  • We still have ambiguity on the left-hand side:

A :+: A : ≺: A :+: B

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 13

slide-62
SLIDE 62

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Post-Processing

This is almost what we want.

  • We avoid ambiguity on the right-hand side:

A : ≺: A :+: A :+: C

  • We still have ambiguity on the left-hand side:

A :+: A : ≺: A :+: B

Solution: check for duplicates in Prf

type family Dupl (p :: Prf ) :: Bool where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 13

slide-63
SLIDE 63

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Post-Processing

This is almost what we want.

  • We avoid ambiguity on the right-hand side:

A : ≺: A :+: A :+: C

  • We still have ambiguity on the left-hand side:

A :+: A : ≺: A :+: B

Solution: check for duplicates in Prf

type family Dupl (p :: Prf ) :: Bool where . . . Sum (Left Refl) (Left Refl)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 13

slide-64
SLIDE 64

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Are we there yet?

  • Construct proof p for f :

≺ ≺: g

  • Check whether p proves f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 14

slide-65
SLIDE 65

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Are we there yet?

  • Construct proof p for f :

≺ ≺: g

  • Check whether p proves f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 14

slide-66
SLIDE 66

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Are we there yet?

  • Construct proof p for f :

≺ ≺: g

  • Check whether p proves f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 14

slide-67
SLIDE 67

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Are we there yet?

  • Construct proof p for f :

≺ ≺: g

  • Check whether p proves f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 14

slide-68
SLIDE 68

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) instance f : ≺: f where . . . instance f : ≺: (f :+: g2) where . . . instance f : ≺: g2 ⇒ f : ≺: (g1 :+: g2) where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-69
SLIDE 69

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) instance f : ≺: f where . . . instance f : ≺: g1 ⇒ f : ≺: (g1 :+: g2) where . . . instance f : ≺: g2 ⇒ f : ≺: (g1 :+: g2) where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-70
SLIDE 70

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class f : ≺: g where inj :: f a → g a prj :: g a → Maybe (f a) instance f : ≺: f where . . . instance f : ≺: g1 ⇒ f : ≺: (g1 :+: g2) where . . . instance f : ≺: g2 ⇒ f : ≺: (g1 :+: g2) where . . . instance ( f1 : ≺: g, f2 : ≺: g) ⇒ (f1 :+: f2) : ≺: g where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-71
SLIDE 71

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class Sub f g where inj :: f a → g a prj :: g a → Maybe (f a) instance Sub f f where . . . instance Sub f g1 ⇒ Sub f (g1 :+: g2) where . . . instance Sub f g2 ⇒ Sub f (g1 :+: g2) where . . . instance (Sub f1 g, Sub f2 g) ⇒ Sub (f1 :+: f2) g where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-72
SLIDE 72

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class Sub (e :: Emb) f g where inj :: f a → g a prj :: g a → Maybe (f a) instance Sub f f where . . . instance Sub f g1 ⇒ Sub f (g1 :+: g2) where . . . instance Sub f g2 ⇒ Sub f (g1 :+: g2) where . . . instance (Sub f1 g, Sub f2 g) ⇒ Sub (f1 :+: f2) g where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-73
SLIDE 73

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class Sub (e :: Emb) f g where inj :: f a → g a prj :: g a → Maybe (f a) instance Sub (Found Refl) f f where . . . instance Sub (Found p) f g1 ⇒ Sub (Found (Left p)) f (g1 :+: g2) where . . . instance Sub (Found p) f g2 ⇒ Sub (Found (Right p)) f (g1 :+: g2) where . . . instance (Sub (Found p1) f1 g, Sub (Found p2) f2 g) ⇒ Sub (Found (Sum p1 p2)) (f1 :+: f2) g where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-74
SLIDE 74

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Derive inj and prj

class Sub (e :: Emb) f g where inj :: f a → g a prj :: g a → Maybe (f a) type f : ≺: g = Sub (Embed f g) f g instance Sub (Found Refl) f f where . . . instance Sub (Found p) f g1 ⇒ Sub (Found (Left p)) f (g1 :+: g2) where . . . instance Sub (Found p) f g2 ⇒ Sub (Found (Right p)) f (g1 :+: g2) where . . . instance (Sub (Found p1) f1 g, Sub (Found p2) f2 g) ⇒ Sub (Found (Sum p1 p2)) (f1 :+: f2) g where . . .

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 15

slide-75
SLIDE 75

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Conclusion

  • This approach generalises to similar applications
  • Improves type class-based implementation in many

aspects

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 16

slide-76
SLIDE 76

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Conclusion

  • This approach generalises to similar applications
  • Improves type class-based implementation in many

aspects

  • But:
  • We need a way to customise error messages.
  • Compile time performance unpredictable.

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 16

slide-77
SLIDE 77

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Conclusion

  • This approach generalises to similar applications
  • Improves type class-based implementation in many

aspects

  • But:
  • We need a way to customise error messages.
  • Compile time performance unpredictable.
  • Implemented in the compdata package

> cabal install compdata

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 16

slide-78
SLIDE 78

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Discussion

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 17

slide-79
SLIDE 79

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ?

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-80
SLIDE 80

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C))

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-81
SLIDE 81

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C)) The original implementation would give: No instance for (A :<: C)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-82
SLIDE 82

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C))

  • A :+: A :

≺: A :+: B ? No instance for (Sub Ambiguous (A :+: A) (A :+: B))

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-83
SLIDE 83

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C))

  • A :+: A :

≺: A :+: B ? No instance for (Sub Ambiguous (A :+: A) (A :+: B))

  • A :

≺: A :+: B ?

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-84
SLIDE 84

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C))

  • A :+: A :

≺: A :+: B ? No instance for (Sub Ambiguous (A :+: A) (A :+: B))

  • a :

≺: a :+: B ?

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-85
SLIDE 85

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Error Messages

  • A :

≺: B :+: C ? No instance for (Sub NotFound A (B :+: C))

  • A :+: A :

≺: A :+: B ? No instance for (Sub Ambiguous (A :+: A) (A :+: B))

  • a :

≺: a :+: B ? No instance for (Sub (Post (Embed a (a :+: B))) a (a :+: B))

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 18

slide-86
SLIDE 86

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-87
SLIDE 87

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-88
SLIDE 88

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)
  • Slightly different implementation: O(2n)

(but essentially the same)

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-89
SLIDE 89

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)
  • Slightly different implementation: O(2n)

(but essentially the same)

  • micro benchmark:
  • derive F :

≺: G

  • 9 summands in F and G

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-90
SLIDE 90

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)
  • Slightly different implementation: O(2n)

(but essentially the same)

  • micro benchmark:
  • derive F :

≺: G

  • 9 summands in F and G
  • Implementation presented here: 0.5s

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-91
SLIDE 91

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)
  • Slightly different implementation: O(2n)

(but essentially the same)

  • micro benchmark:
  • derive F :

≺: G

  • 9 summands in F and G
  • Implementation presented here: 0.5s
  • Naive implementation: 45s

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19

slide-92
SLIDE 92

u n i v e r s i t y o f c o p e n h a g e n d e p a r t m e n t o f c o m p u t e r s c i e n c e

Compile Time Performance

  • If done “wrong”, this implementation can be very slow!
  • Implementation presented here: O(n2)
  • Slightly different implementation: O(2n)

(but essentially the same)

  • micro benchmark:
  • derive F :

≺: G

  • 9 summands in F and G
  • Implementation presented here: 0.5s
  • Naive implementation: 45s
  • Type families on kind ∗ are expensive!

Patrick Bahr — Composing and Decomposing Data Types — WGP ’14, 31st August, 2014 Slide 19