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
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
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
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
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
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
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 injection not unique! 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
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 injection not unique! 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
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 injection not unique! Multiple occurrences of signatures are rejected: A : �≺ : A :+: A :+: C A :+: A : ≺ : A :+: B “injection” not injective! Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 injection not unique! Multiple occurrences of signatures are rejected: A : �≺ : A :+: A :+: C A :+: A : �≺ : A :+: B “injection” not injective! Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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
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
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
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
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
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
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
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 f 1 g , Desug f 2 g ) ⇒ Desug ( f 1 :+: f 2 ) 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
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 f 1 g , Desug f 2 g ) ⇒ Desug ( f 1 :+: f 2 ) 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
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 f 1 g , Desug f 2 g ) ⇒ Desug ( f 1 :+: f 2 ) 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
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
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
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
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
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
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
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
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
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
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
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
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 : ≺ : g 1 p : f : ≺ : g 2 Left p : f : ≺ : g 1 :+: g 2 Right p : f : ≺ : g 1 :+: g 2 Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Proof Objects Definition data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : f : ≺ : f p : f : ≺ : g 1 p : f : ≺ : g 2 Left p : f : ≺ : g 1 :+: g 2 Right p : f : ≺ : g 1 :+: g 2 p 1 : f 1 : ≺ : g p 2 : f 2 : ≺ : g Sum p 1 p 2 : f 1 :+: f 2 : ≺ : g Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Proof Objects Definition kind data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : f : ≺ : f p : f : ≺ : g 1 p : f : ≺ : g 2 Left p : f : ≺ : g 1 :+: g 2 Right p : f : ≺ : g 1 :+: g 2 p 1 : f 1 : ≺ : g p 2 : f 2 : ≺ : g Sum p 1 p 2 : f 1 :+: f 2 : ≺ : g Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Proof Objects Definition type kind data Pos = Here | Left Pos | Right Pos | Sum Pos Pos Here : f : ≺ : f p : f : ≺ : g 1 p : f : ≺ : g 2 Left p : f : ≺ : g 1 :+: g 2 Right p : f : ≺ : g 1 :+: g 2 p 1 : f 1 : ≺ : g p 2 : f 2 : ≺ : g Sum p 1 p 2 : f 1 :+: f 2 : ≺ : g Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Proof Objects Definition type kind data Pos = Here | Left Pos | Right Pos | Sum Pos Pos type constructor Here : f : ≺ : f p : f : ≺ : g 1 p : f : ≺ : g 2 Left p : f : ≺ : g 1 :+: g 2 Right p : f : ≺ : g 1 :+: g 2 p 1 : f 1 : ≺ : g p 2 : f 2 : ≺ : g Sum p 1 p 2 : f 1 :+: f 2 : ≺ : g Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Construct Proof Objects data Emb = Found Pos | NotFound | Ambiguous Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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
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 = Found Here Embed f f Embed ( f 1 :+: f 2 ) g = Sum ′ ( Embed f 1 g ) ( Embed f 2 g ) Embed f ( g 1 :+: g 2 ) = Choose ( Embed f g 1 ) ( Embed f g 2 ) Embed f g = NotFound Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Construct Proof Objects data Emb = Found Pos | NotFound | Ambiguous type family Embed ( f :: ∗ → ∗ ) ( g :: ∗ → ∗ ) :: Emb where = Found Here Embed f f Embed ( f 1 :+: f 2 ) g = Sum ′ ( Embed f 1 g ) ( Embed f 2 g ) Embed f ( g 1 :+: g 2 ) = Choose ( Embed f g 1 ) ( Embed f g 2 ) Embed f g = NotFound type family Choose ( e 1 :: Emb ) ( e 2 :: Emb ) :: Emb where Choose ( Found p 1 ) ( Found p 1 ) = Ambiguous = Ambiguous Choose Ambiguous e 2 Choose e 1 Ambiguous = Ambiguous Choose ( Found p 1 ) e 2 = Found ( Left p 1 ) Choose e 1 ( Found p 2 ) = Found ( Right p 2 ) = NotFound Choose NotFound NotFound Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Post-Processing This is almost what we want. Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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
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
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
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 Sum ( Left Here ) ( Left Here ) • 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
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
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
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
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
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 f : ≺ : g where class inj :: f a → g a prj :: g a → Maybe ( f a ) instance f : ≺ : f where . . . f : ≺ : ( f :+: g 2 ) where . . . instance instance f : ≺ : g 2 ⇒ f : ≺ : ( g 1 :+: g 2 ) where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 . . . ( f :+: g 2 ) where . . . instance Sub f instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 g 1 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 g 1 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance ( Sub f 1 g , Sub f 2 g ) ⇒ ( f 1 :+: f 2 ) g Sub where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 g 1 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance ( Sub f 1 g , Sub f 2 g ) ⇒ ( f 1 :+: f 2 ) g Sub where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Derive inj and prj Here : f : ≺ : f 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 g 1 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance ( Sub f 1 g , Sub f 2 g ) ⇒ ( f 1 :+: f 2 ) g Sub where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 p : f : ≺ : g 1 Derive inj and prj Left p : f : ≺ : g 1 :+: g 2 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 g 1 ⇒ Sub ( Found ( Left p )) f ( g 1 :+: g 2 ) where . . . instance Sub f g 2 ⇒ Sub f ( g 1 :+: g 2 ) where . . . instance ( Sub f 1 g , Sub f 2 g ) ⇒ ( f 1 :+: f 2 ) g Sub where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 p : f : ≺ : g 2 Derive inj and prj Right p : f : ≺ : g 1 :+: g 2 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 g 1 ⇒ Sub ( Found ( Left p )) f ( g 1 :+: g 2 ) where . . . instance Sub ( Found p ) f g 2 ⇒ Sub ( Found ( Right p )) f ( g 1 :+: g 2 ) where . . . instance ( Sub f 1 g , Sub f 2 g ) ⇒ ( f 1 :+: f 2 ) g Sub where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 p 1 : f 1 : ≺ : g p 2 : f 2 : ≺ : g Derive inj and prj Sum p 1 p 2 : f 1 :+: f 2 : ≺ : g 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 g 1 ⇒ Sub ( Found ( Left p )) f ( g 1 :+: g 2 ) where . . . instance Sub ( Found p ) f g 2 ⇒ Sub ( Found ( Right p )) f ( g 1 :+: g 2 ) where . . . instance ( Sub ( Found p 1 ) f 1 g , Sub ( Found p 2 ) f 2 g ) ⇒ Sub ( Found ( Sum p 1 p 2 )) ( f 1 :+: f 2 ) g where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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 g 1 ⇒ Sub ( Found ( Left p )) f ( g 1 :+: g 2 ) where . . . instance Sub ( Found p ) f g 2 ⇒ Sub ( Found ( Right p )) f ( g 1 :+: g 2 ) where . . . instance ( Sub ( Found p 1 ) f 1 g , Sub ( Found p 2 ) f 2 g ) ⇒ Sub ( Found ( Sum p 1 p 2 )) ( f 1 :+: f 2 ) g where . . . Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 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
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
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
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
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
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
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
Type-Level Programming in Haskell
Type-Level Programming in Haskell • Now : ≺ : has the properties we want / expect • Avoid “ambiguous” subtyping • New isomorphism constraint : ≃ :
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
Type-Level Programming in Haskell
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
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 ( n 2 ) Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Compile Time Performance • If done “wrong”, this implementation can be very slow! • Implementation presented here: O ( n 2 ) • Slightly different implementation: O (2 n ) (but essentially the same) Patrick Bahr — Composing and Decomposing Data Types — 20th June, 2014 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 Compile Time Performance • If done “wrong”, this implementation can be very slow! • Implementation presented here: O ( n 2 ) • Slightly different implementation: O (2 n ) (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
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 ( n 2 ) • Slightly different implementation: O (2 n ) (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
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 ( n 2 ) • Slightly different implementation: O (2 n ) (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
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 ( n 2 ) • Slightly different implementation: O (2 n ) (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
Type-Level Programming in Haskell
Recommend
More recommend