Composing and Decomposing Data Types Data Types ` a la Carte with - - PowerPoint PPT Presentation

composing and decomposing data types
SMART_READER_LITE
LIVE PREVIEW

Composing and Decomposing Data Types Data Types ` a la Carte with - - 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 Data Types ` a la Carte with Closed Type Families Patrick Bahr University of Copenhagen,


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

Data Types ` a la Carte with Closed Type Families Patrick Bahr

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

20th June, 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

Goal

Improve Haskell implementation of Data Types ` a la Carte:

  • More flexible
  • Improved error reporting
  • New use cases

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Goal

Improve Haskell implementation of Data Types ` a la Carte:

  • More flexible
  • Improved error reporting
  • New use cases

How?

Using closed type families

  • New feature in latest version of GHC
  • Type-level functions
  • Pattern matching similar(-ish) to term-level functions

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Data Types ` a la Carte

Idea: Decompose data types into two-level types:

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 3

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

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 — 20th June, 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

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 — 20th June, 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

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 — 20th June, 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

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 — 20th June, 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

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 — 20th June, 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

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 — 20th June, 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

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 — 20th June, 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 (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 — 20th June, 2014 Slide 4

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)

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 — 20th June, 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)

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 — 20th June, 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

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 — 20th June, 2014 Slide 5

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

Limitations of : ≺:

Definition of : ≺:

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

  • No backtracking!

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 5

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 : ≺: (f :+: f2) where . . . instance (f : ≺: f2) ⇒ f : ≺: (f1 :+: f2) where . . .

  • No backtracking!

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 . . .

  • No backtracking!
  • Asymmetric treatment of :+:
  • Left-hand side is not inspected

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 . . .

  • No backtracking!
  • Asymmetric treatment of :+:

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

  • Left-hand side is not inspected

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 . . .

  • No backtracking!
  • Asymmetric treatment of :+:

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

  • Left-hand side is not inspected

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 . . .

  • No backtracking!
  • Asymmetric treatment of :+:

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

  • Left-hand side is not inspected

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

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 . . .

  • No backtracking!
  • Asymmetric treatment of :+:

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

  • Left-hand side is not inspected

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

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Contributions We re-implemented : ≺: such that:

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

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 6

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

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 7

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

Improved subtyping constraint : ≺:

Subtyping : ≺: behaves as intuitively expected

f : ≺: g ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in g”

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 7

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

f : ≺: g ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in g” C :+: A : ≺: A :+: B :+: C

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in g” C :+: A : ≺: A :+: B :+: C

Avoid ambiguous subtyping

Multiple occurrences of signatures are rejected:

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” ⊆ “set of signatures in 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 — 20th June, 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

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ “set of signatures in f ” = “set of signatures in g”

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 8

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

Type isomorphism constraint :≃:

We can express isomorphism :≃:

f :≃: g ⇐ ⇒ “set of signatures in f ” = “set of signatures in g” Easy to implement: f :≃: g = (f : ≺: g, g : ≺: f )

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 8

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 ⇐ ⇒ “set of signatures in f ” = “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” = “set of signatures in 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 — 20th June, 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 ⇐ ⇒ “set of signatures in f ” = “set of signatures in 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 — 20th June, 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

Example: Desugaring

data Dbl a = Double a

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 9

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

Example: Desugaring

data Dbl a = Double a class Desug f g where desugAlg :: f (Fix g) → Fix g

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 9

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

Example: Desugaring

data Dbl a = Double a class Desug f g where desugAlg :: f (Fix g) → Fix g instance (Desug f1 g, Desug f2 g) ⇒ Desug (f1 :+: f2) g where desugAlg (Inl x) = desugAlg x desugAlg (Inr x) = desugAlg x instance (Arith : ≺: g) ⇒ Desug Dbl g where desugAlg (Double x) = add x x instance (f : ≺: g) ⇒ Desug f g where desugAlg = In . inj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Example: Desugaring

data Dbl a = Double a class Desug f g where desugAlg :: f (Fix g) → Fix g instance (Desug f1 g, Desug f2 g) ⇒ Desug (f1 :+: f2) g where desugAlg (Inl x) = desugAlg x desugAlg (Inr x) = desugAlg x instance (Arith : ≺: g) ⇒ Desug Dbl g where desugAlg (Double x) = add x x instance (f : ≺: g) ⇒ Desug f g where desugAlg = In . inj desugar :: (Desug f g, Functor f ) ⇒ Fix f → Fix g desugar = fold desugAlg

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 9

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

Example: Desugaring

data Dbl a = Double a class Desug f g where desugAlg :: f (Fix g) → Fix g instance (Desug f1 g, Desug f2 g) ⇒ Desug (f1 :+: f2) g where desugAlg (Inl x) = desugAlg x desugAlg (Inr x) = desugAlg x instance (Arith : ≺: g) ⇒ Desug Dbl g where desugAlg (Double x) = add x x instance (f : ≺: g) ⇒ Desug f g where desugAlg = In . inj desugar :: Fix (Dbl :+: Arith :+: Mul) → Fix (Arith :+: Mul) desugar = fold desugAlg

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 9

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

Example: Desugaring (cont.)

desugar :: (f :≃: g :+: Dbl, Arith : ≺: g, Functor f ) ⇒ Fix f → Fix g desugar = fold desugAlg

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Example: Desugaring (cont.)

desugar :: (f :≃: g :+: Dbl, Arith : ≺: g, Functor f ) ⇒ Fix f → Fix g desugar = fold desugAlg desugAlg :: (f :≃: g :+: Dbl, Arith : ≺: g) ⇒ f (Fix g) → Fix g desugAlg e = split e (λx → In x) (λ(Double x) → add x x)

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Example: Desugaring (cont.)

desugar :: (f :≃: g :+: Dbl, Arith : ≺: g, Functor f ) ⇒ Fix f → Fix g desugar = fold desugAlg desugAlg :: (f :≃: g :+: Dbl, Arith : ≺: g) ⇒ f (Fix g) → Fix g desugAlg e = split e (λx → In x) (λ(Double x) → add x x) desugAlg′ :: (f :≃: g :+: Dbl, Arith : ≺: g, Mul : ≺: g) ⇒ f (Fix g) → Fix g desugAlg′ e = split e (λx → In x) (λ(Double x) → mul (val 2) x)

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Implementation of : ≺:

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 11

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
  • check whether f :

≺: g

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 12

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

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 — 20th June, 2014 Slide 12

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

Idea

Type-level function Embed:

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

≺: g

  • if check is successful: produce proof object for f :

≺: g Derive implementation of inj and prj:

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 12

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

Idea

Type-level function Embed:

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

≺: g

  • if check is successful: produce proof object 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 — 20th June, 2014 Slide 12

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

Idea

Type-level function Embed:

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

≺: g

  • if check is successful: produce proof object 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 — 20th June, 2014 Slide 12

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 Pos = Here | Left Pos | Right Pos | Sum Pos Pos

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 13

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 Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : f : ≺: f

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 13

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 Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : 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 — 20th June, 2014 Slide 13

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

Proof Objects

Definition

data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : 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 — 20th June, 2014 Slide 13

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

Proof Objects

Definition

data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : 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 — 20th June, 2014 Slide 13

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

Proof Objects

Definition

data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : 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 — 20th June, 2014 Slide 13

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

Proof Objects

Definition

data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : 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 — 20th June, 2014 Slide 13

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

Construct Proof Objects

data Emb = Found Pos | NotFound | Ambiguous

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 14

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

Construct Proof Objects

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

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 14

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

Construct Proof Objects

data Emb = Found Pos | NotFound | Ambiguous type family Embed (f :: ∗ → ∗) (g :: ∗ → ∗) :: Emb where Embed f f = Found Here 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 — 20th June, 2014 Slide 14

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

Construct Proof Objects

data Emb = Found Pos | NotFound | Ambiguous type family Embed (f :: ∗ → ∗) (g :: ∗ → ∗) :: Emb where Embed f f = Found Here 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 p1) = 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 — 20th June, 2014 Slide 14

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.

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 15

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

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 — 20th June, 2014 Slide 15

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

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 — 20th June, 2014 Slide 15

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

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 Pos

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

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 15

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

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 Pos

type family Dupl (p :: Pos) :: Bool where . . . Sum (Left Here) (Left Here)

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 15

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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 16

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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 16

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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 16

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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 16

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 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 — 20th June, 2014 Slide 17

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 f g where inj :: f a → g a prj :: g a → Maybe (f a) instance Sub f f where . . . instance Sub f (f :+: g2) where . . . instance Sub f g2 ⇒ Sub f (g1 :+: g2) where . . .

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 17

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 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 . . .

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 17

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

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 — 20th June, 2014 Slide 17

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

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 — 20th June, 2014 Slide 17

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

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 Here) 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 . . . Here : f : ≺: f

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 17

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

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 Here) f f where . . . instance Sub (Found p) f g1 ⇒ Sub (Found (Left p)) 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 . . . p : f : ≺: g1 Left p : f : ≺: g1 :+: g2

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

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 Here) 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 f1 g, Sub f2 g) ⇒ Sub (f1 :+: f2) g where . . . p : f : ≺: g2 Right p : f : ≺: g1 :+: g2

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 17

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

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 Here) 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 . . . p1 : f1 : ≺: g p2 : f2 : ≺: g Sum p1 p2 : f1 :+: f2 : ≺: g

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 17

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

Derive inj and prj

class Sub (e :: Emb) f g where inj :: Proxy e → f a → g a prj :: Proxy e → g a → Maybe (f a) instance Sub (Found Here) 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 — 20th June, 2014 Slide 17

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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj
  • Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Are we there yet?

  • Check whether f :

≺: g

  • Construct proof for f :

≺: g

  • Derive inj and prj

(sort of)

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Final Implementation of : ≺:

class Sub (e :: Emb) f g where inj :: Proxy e → f a → g a prj :: Proxy e → g a → Maybe (f a)

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 19

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

Final Implementation of : ≺:

class Sub (e :: Emb) f g where inj :: Proxy e → f a → g a prj :: Proxy e → g a → Maybe (f a) type f : ≺: g = Sub (Post (Embed f g)) f g

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Final Implementation of : ≺:

class Sub (e :: Emb) f g where inj′ :: Proxy e → f a → g a prj′ :: Proxy e → g a → Maybe (f a) type f : ≺: g = Sub (Post (Embed f g)) f g

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 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

Final Implementation of : ≺:

class Sub (e :: Emb) f g where inj′ :: Proxy e → f a → g a prj′ :: Proxy e → g a → Maybe (f a) type f : ≺: g = Sub (Post (Embed f g)) f g inj :: (f : ≺: g) ⇒ f a → g a inj = inj′ (P :: Proxy (Post (Embed f g))) prj :: (f : ≺: g) ⇒ g a → Maybe (f a) prj = prj′ (P :: Proxy (Post (Embed f g)))

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 19

slide-89
SLIDE 89

Type-Level Programming in Haskell

slide-90
SLIDE 90

Type-Level Programming in Haskell

  • Now :

≺: has the properties we want / expect

  • Avoid “ambiguous” subtyping
  • New isomorphism constraint :≃:
slide-91
SLIDE 91

Type-Level Programming in Haskell

  • Now :

≺: has the properties we want / expect

  • Avoid “ambiguous” subtyping
  • New isomorphism constraint :≃:
  • You can try it:

> cabal install compdata

slide-92
SLIDE 92

Type-Level Programming in Haskell

slide-93
SLIDE 93

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 — 20th June, 2014 Slide 22

slide-94
SLIDE 94

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 — 20th June, 2014 Slide 22

slide-95
SLIDE 95

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 — 20th June, 2014 Slide 22

slide-96
SLIDE 96

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 — 20th June, 2014 Slide 22

slide-97
SLIDE 97

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 — 20th June, 2014 Slide 22

slide-98
SLIDE 98

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 — 20th June, 2014 Slide 22

slide-99
SLIDE 99

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 — 20th June, 2014 Slide 22

slide-100
SLIDE 100

Type-Level Programming in Haskell

slide-101
SLIDE 101

Type-Level Programming in Haskell

slide-102
SLIDE 102

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 — 20th June, 2014 Slide 24

slide-103
SLIDE 103

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 — 20th June, 2014 Slide 24

slide-104
SLIDE 104

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 — 20th June, 2014 Slide 24

slide-105
SLIDE 105

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 — 20th June, 2014 Slide 24

slide-106
SLIDE 106

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 — 20th June, 2014 Slide 24

slide-107
SLIDE 107

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 — 20th June, 2014 Slide 24

slide-108
SLIDE 108

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 — 20th June, 2014 Slide 24

slide-109
SLIDE 109

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

  • We can do cool stuff with closed type families.

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 25

slide-110
SLIDE 110

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

  • We can do cool stuff with closed type families.
  • But:
  • Compile time performance unpredictable.
  • We need a way to customise error messages.

Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 Slide 25