Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Embedded Pattern Matching

Embedded Pattern Matching

Presented at Haskell Symposium 2022: https://icfp22.sigplan.org/home/haskellsymp-2022
Paper: https://dl.acm.org/doi/10.1145/3546189.3549917
Artefact: https://github.com/tmcdonell/embedded-pattern-matching/
Video: https://youtu.be/Y1s28Sm5s8E

Haskell is a popular choice for hosting deeply embedded languages. A recurring challenge for these embeddings is how to seamlessly integrate user defined algebraic data types. In particular, one important, convenient, and expressive feature for creating and inspecting data—pattern matching—is not directly available on embedded terms. In this paper, we present a novel technique, embedded pattern matching, which enables a natural and user friendly embedding of user defined algebraic data types into the embedded language. Our technique enables users to pattern match on terms in the embedded language in much the same way they would in the host language.

Trevor L. McDonell

September 16, 2022
Tweet

More Decks by Trevor L. McDonell

Other Decks in Research

Transcript

  1. Algebraic data types data List a = Nil | Cons

    a (List a) length : : List a - > Int length Nil = 0 length (Cons _ xs) = 1 + length xs 2
  2. ans : : Exp Int ans = Succ (Lit 41)

    Embedded languages https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/gadt.html data Exp a where Lit : : Int - > Exp Int Succ : : Exp Int - > Exp Int . . . 3
  3. ans : : Exp Int ans = Succ (Lit 41)

    Embedded languages https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/gadt.html data Exp a where Lit : : Int - > Exp Int Succ : : Exp Int - > Exp Int . . . 3 eval : : Exp Int - > Int eval (Lit i) = i eval (Succ x) = 1 + eval x . . .
  4. ans : : Exp Int ans = Succ (Lit 41)

    Embedded languages https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/gadt.html data Exp a where Lit : : Int - > Exp Int Succ : : Exp Int - > Exp Int . . . 3 eval : : Exp Int - > Int eval (Lit i) = i eval (Succ x) = 1 + eval x . . .
  5. ans : : Exp Int ans = Succ (Lit 41)

    Embedded languages https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/gadt.html data Exp a where Lit : : Int - > Exp Int Succ : : Exp Int - > Exp Int . . . 3 eval : : Exp Int - > Int eval (Lit i) = i eval (Succ x) = 1 + eval x . . .
  6. Embedded languages … with ADTs? length’ : : Exp (List

    a) - > Exp Int length’ = . . . ? 4
  7. Embedded languages … with ADTs? length’ : : Exp (List

    a) - > Exp Int length’ = . . . ? 4
  8. The Problem • Can we have: - A deeply embedded

    language, supporting… - User-de fi ned algebraic data-types, together with… - Construction and pattern matching on embedded terms of algebraic data type? 5 https://poorlydrawnlines.com/comic/the-one-they-call/
  9. Option 1: Lots of type errors • De fi ne

    functions to “push” a constructor through an expression 6 Data.Array.Accelerate: https://hackage.haskell.org/package/accelerate-1.3.0.0/docs/Data-Array-Accelerate.html#g:47 pair : : Exp a - > Exp b - > Exp (a, b) pair x y = lift (x, y) fst : : Exp (a, b) - > Exp a fst p = let (a, _) = unlift p in a
  10. Option 1: Lots of type errors • De fi ne

    functions to “push” a constructor through an expression 6 Data.Array.Accelerate: https://hackage.haskell.org/package/accelerate-1.3.0.0/docs/Data-Array-Accelerate.html#g:47 pair : : Exp a - > Exp b - > Exp (a, b) pair x y = lift (x, y) fst : : Exp (a, b) - > Exp a fst p = let (a, _) = unlift p in a Lift.hs:14 : 29 : error: • Couldn't match type ‘b’ with ‘Plain b0’ ‘b’ is a rigid type variable bound by the type signature for: Lift.fst : : forall a b. (Elt a, Elt b) = > Exp (a, b) - > Exp a at Lift.hs:13 : 1-44 Expected type: Exp (Plain (Exp a, b0)) Actual type: Exp (a, b) • In the f i rst argument of ‘unlift’, namely ‘p’ In the expression: unlift p In a pattern binding: (a, _) = unlift p • Relevant bindings include p : : Exp (a, b) (bound at Lift.hs:14 : 5) fst : : Exp (a, b) - > Exp a (bound at Lift.hs:14 : 1) | 14 | fst p = let (a, _) = unlift p in a | ^
  11. Option 2: Don’t do that • Keep terms in the

    “unlifted” form - Avoids the need to lift and unlift terms - Relies on compiler magic to remove redundancy 7 Combining Deep and Shallow Embedding for EDSL, Svenningsson J and Axelsson, E. dup : : (Exp a, Exp b) dup = ( fst extremly_expensive_thing , snd extremly_expensive_thing ) fst : : (Exp a, Exp b) - > Exp a fst (a, _) = a
  12. A subtle limitation • Both of these approaches require the

    constructor to be polymorphic - There is no way to “unlift” a term of: 8 data Point = Point F l oat F l oat
  13. The killer • Neither approach supports sum data types -

    Although for a selection of “built in” types you can use a combinator instead of pattern matching 9 maybe : : Exp b - - default value if Nothing - > (Exp a - > Exp b) - - function to apply if Just - > Exp (Maybe a) - > Exp b maybe = . . . ?
  14. Grammar • A minimal expression language - Variables, application, abstraction,

    etc. are standard - Construction and access to pairs, as well as case expressions - Uniform representation of all user-de fi ned data-types as nested pairs 11 Embedded Pa￿ern Matching 1:9 ⇢ ::= ⇠ Constant | G Variable | let E0A = ⇢ in ⇢ Let binding | _G. ⇢ Abstraction | ⇢ ⇢ Application | ) Tuples | c ⇢ Projection | CA024 ⇢ Pattern match | ⇢ [ ⇢1 ...⇢= ] Case expression ) ::= () Unit | ⇢ Expression | ) ) Pair c ::= ... Projections ⇠ ::= ... Constants E0A, G ::= ... Variable name CA024 ::= ... Match trace Fig. 4. The grammar of our embedded language
  15. Grammar • A minimal expression language - Variables, application, abstraction,

    etc. are standard - Construction and access to pairs, as well as case expressions - Uniform representation of all user-de fi ned data-types as nested pairs 11 Embedded Pa￿ern Matching 1:9 ⇢ ::= ⇠ Constant | G Variable | let E0A = ⇢ in ⇢ Let binding | _G. ⇢ Abstraction | ⇢ ⇢ Application | ) Tuples | c ⇢ Projection | CA024 ⇢ Pattern match | ⇢ [ ⇢1 ...⇢= ] Case expression ) ::= () Unit | ⇢ Expression | ) ) Pair c ::= ... Projections ⇠ ::= ... Constants E0A, G ::= ... Variable name CA024 ::= ... Match trace Fig. 4. The grammar of our embedded language
  16. Grammar • A minimal expression language - Variables, application, abstraction,

    etc. are standard - Construction and access to pairs, as well as case expressions - Uniform representation of all user-de fi ned data-types as nested pairs 11 Embedded Pa￿ern Matching 1:9 ⇢ ::= ⇠ Constant | G Variable | let E0A = ⇢ in ⇢ Let binding | _G. ⇢ Abstraction | ⇢ ⇢ Application | ) Tuples | c ⇢ Projection | CA024 ⇢ Pattern match | ⇢ [ ⇢1 ...⇢= ] Case expression ) ::= () Unit | ⇢ Expression | ) ) Pair c ::= ... Projections ⇠ ::= ... Constants E0A, G ::= ... Variable name CA024 ::= ... Match trace Fig. 4. The grammar of our embedded language
  17. Embedding Point 12 data Point = Point F l oat

    F l oat Surface type (extensible)
  18. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) Surface type (extensible)
  19. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) Representation type (closed) Surface type (extensible)
  20. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y Representation type (closed) Surface type (extensible)
  21. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple Representation type (closed) Surface type (extensible)
  22. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple $ Unit `Pair` Exp x `Pair` Exp y Representation type (closed) Surface type (extensible)
  23. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple $ Unit `Pair` Exp x `Pair` Exp y matchPoint : : Exp Point - > (Exp F l oat, Exp F l oat) Representation type (closed) Surface type (extensible)
  24. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple $ Unit `Pair` Exp x `Pair` Exp y matchPoint : : Exp Point - > (Exp F l oat, Exp F l oat) matchPoint p = ( Prj . . . p , Prj . . . p ) Representation type (closed) Surface type (extensible)
  25. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple $ Unit `Pair` Exp x `Pair` Exp y matchPoint : : Exp Point - > (Exp F l oat, Exp F l oat) matchPoint p = ( Prj . . . p , Prj . . . p ) Representation type (closed) Surface type (extensible) Haskell pair of 
 embedded expressions
  26. Embedding Point 12 data Point = Point F l oat

    F l oat - - EltR Point = (((), F l oat), F l oat) buildPoint : : Exp F l oat - > Exp F l oat - > Exp Point buildPoint x y = Tuple $ Unit `Pair` Exp x `Pair` Exp y matchPoint : : Exp Point - > (Exp F l oat, Exp F l oat) matchPoint p = ( Prj . . . p , Prj . . . p ) Representation type (closed) Surface type (extensible) Haskell pair of 
 embedded expressions Can only ever add 
 new embedded terms
  27. Pattern synonyms • A Haskell extension which allows programmers to

    de fi ne new patterns 14 Pattern Synonyms, Pickering, M and Érdi, G and Peyton-Jones, S and Eisenburg, R. A. pattern Point_ : : Exp F l oat - > Exp F l oat - > Exp Point pattern Point_ x y < - (matchPoint - > (x, y)) where Point_ = buildPoint
  28. Pattern synonyms • A Haskell extension which allows programmers to

    de fi ne new patterns - The builder is run when used as an expression (when constructing) 14 Pattern Synonyms, Pickering, M and Érdi, G and Peyton-Jones, S and Eisenburg, R. A. pattern Point_ : : Exp F l oat - > Exp F l oat - > Exp Point pattern Point_ x y < - (matchPoint - > (x, y)) where Point_ = buildPoint
  29. Pattern synonyms • A Haskell extension which allows programmers to

    de fi ne new patterns - The builder is run when used as an expression (when constructing) - The matcher is run when used as a pattern (when matching) 14 Pattern Synonyms, Pickering, M and Érdi, G and Peyton-Jones, S and Eisenburg, R. A. pattern Point_ : : Exp F l oat - > Exp F l oat - > Exp Point pattern Point_ x y < - (matchPoint - > (x, y)) where Point_ = buildPoint
  30. Pattern synonyms • A Haskell extension which allows programmers to

    de fi ne new patterns - The builder is run when used as an expression (when constructing) - The matcher is run when used as a pattern (when matching) 14 Pattern Synonyms, Pickering, M and Érdi, G and Peyton-Jones, S and Eisenburg, R. A. pattern Point_ : : Exp F l oat - > Exp F l oat - > Exp Point pattern Point_ x y < - (matchPoint - > (x, y)) where Point_ = buildPoint scale : : Exp F l oat - > Exp Point - > Exp Point scale alpha (Point_ x y) = Point_ (x * alpha) (y * alpha)
  31. Sums • Can we extend this to sum data types?

    15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = . . . ?
  32. Sums • Can we extend this to sum data types?

    15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x - - -XMagicUnderscore . . . ?
  33. Sums • Can we extend this to sum data types?

    - There is a staging problem here 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x - - incomplete!
  34. Sums • Can we extend this to sum data types?

    - There is a staging problem here 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe - - incomplete!
  35. Sums • Can we extend this to sum data types?

    - There is a staging problem here 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe Host runtime generate
 embedded program - - incomplete!
  36. Sums • Can we extend this to sum data types?

    - There is a staging problem here 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe Host runtime Embedded compile time generate
 embedded program Exp compile .o - - incomplete!
  37. Sums • Can we extend this to sum data types?

    - There is a staging problem here 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe Host runtime Embedded compile time Embedded runtime generate
 embedded program Exp compile .o evaluate
 compiled program … - - incomplete!
  38. Sums • Can we extend this to sum data types?

    - There is a staging problem here - Pattern matching occurs during runtime of the host program, 
 but the value will only be known during execution of the embedded program 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe Host runtime Embedded compile time Embedded runtime generate
 embedded program Exp compile .o evaluate
 compiled program … - - incomplete!
  39. Sums • Can we extend this to sum data types?

    - There is a staging problem here - Pattern matching occurs during runtime of the host program, 
 but the value will only be known during execution of the embedded program 15 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case Nothing_ - > d Just_ x - > f x Host compile time .hs GHC .exe Host runtime Embedded compile time Embedded runtime generate
 embedded program Exp compile .o evaluate
 compiled program … Could be executed on 
 a different device, etc. - - incomplete!
  40. Key idea • We need to evaluate this function twice

    - Supply some dummy argument to force each pattern match to succeed in turn - Combine each exposed right-hand-side into an embedded case statement 17 maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = \case - - incomplete! Nothing_ - > d Just_ x - > f x
  41. • We can anticipate what the embedded pattern synonym must

    look like Embedding Maybe pattern Just_ : : Exp a - > Exp (Maybe a) pattern Just_ x < - (matchJust - > Just x) where Just_ = buildJust 18
  42. • We can anticipate what the embedded pattern synonym must

    look like - The builder just wraps the argument in some tag to indicate which variant this term represents Embedding Maybe pattern Just_ : : Exp a - > Exp (Maybe a) pattern Just_ x < - (matchJust - > Just x) where Just_ = buildJust 18
  43. • We can anticipate what the embedded pattern synonym must

    look like - The builder just wraps the argument in some tag to indicate which variant this term represents - But the matcher must signal to the host language pattern matcher somehow Embedding Maybe pattern Just_ : : Exp a - > Exp (Maybe a) pattern Just_ x < - (matchJust - > Just x) where Just_ = buildJust 18
  44. • We can anticipate what the embedded pattern synonym must

    look like - The builder just wraps the argument in some tag to indicate which variant this term represents - But the matcher must signal to the host language pattern matcher somehow Embedding Maybe pattern Just_ : : Exp a - > Exp (Maybe a) pattern Just_ x < - (matchJust - > Just x) where Just_ = buildJust 18
  45. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a))
  46. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) Tag
  47. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) Tag Fields of Nothing
  48. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) Tag Fields of Nothing Fields of Just
  49. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x Tag Fields of Nothing Fields of Just
  50. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple Tag Fields of Nothing Fields of Just
  51. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) Tag Fields of Nothing Fields of Just
  52. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) Tag Fields of Nothing Fields of Just
  53. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) Tag Fields of Nothing Fields of Just
  54. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) Tag Fields of Nothing Fields of Just
  55. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) Tag Fields of Nothing Fields of Just Embedded 
 expression
  56. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value!
  57. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! Embedded expression 
 to extract the value
  58. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) matchJust = \case Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! Embedded expression 
 to extract the value
  59. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) matchJust = \case Match <TRACE 1> a - > Just ( Prj . . . a ) Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! Embedded expression 
 to extract the value
  60. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) matchJust = \case Match <TRACE 1> a - > Just ( Prj . . . a ) Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! Embedded expression 
 to extract the value
  61. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) matchJust = \case Match <TRACE 1> a - > Just ( Prj . . . a ) Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! The Haskell pattern 
 match should succeed Embedded expression 
 to extract the value
  62. Embedding Maybe 19 data Maybe a = Nothing | Just

    a - - EltR (Maybe a) = (Word8, ((), EltR a)) buildJust : : Exp a - > Exp (Maybe a) buildJust x = Tuple $ Exp (Const 1) `Pair` (Unit `Pair` Exp x) matchJust : : Exp (Maybe a) - > Maybe (Exp a) matchJust = \case Match <TRACE 1> a - > Just ( Prj . . . a ) Match _ _ - > Nothing Tag Fields of Nothing Fields of Just Embedded 
 expression Regular Haskell value! The Haskell pattern 
 match should succeed Embedded expression 
 to extract the value
  63. Key idea • We need to evaluate this function twice

    20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  64. Key idea • We need to evaluate this function twice

    20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  65. Key idea • We need to evaluate this function twice

    20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  66. Key idea • We need to evaluate this function twice

    - Match is the dummy argument consumed by the embedded pattern synonym - The <TRACE> indicates which constructor(s) we are interested in 20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  67. Key idea • We need to evaluate this function twice

    - Match is the dummy argument consumed by the embedded pattern synonym - The <TRACE> indicates which constructor(s) we are interested in 20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  68. Key idea • We need to evaluate this function twice

    - Match is the dummy argument consumed by the embedded pattern synonym - The <TRACE> indicates which constructor(s) we are interested in 20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  69. Key idea • We need to evaluate this function twice

    - Match is the dummy argument consumed by the embedded pattern synonym - The <TRACE> indicates which constructor(s) we are interested in 20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  70. Key idea • We need to evaluate this function twice

    - Match is the dummy argument consumed by the embedded pattern synonym - The <TRACE> indicates which constructor(s) we are interested in 20 match_maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b match_maybe d f p = let rhs_nothing = maybe d f (Match <TRACE 0> p) rhs_just = maybe d f (Match <TRACE 1> p) in Case p [ (<TRACE 0>, rhs_nothing) , (<TRACE 1>, rhs_just) ]
  71. • We can automate this process with a single function:

    Embedded Pattern Matching 21 (See paper for details) match : : Matching f = > f - > f
  72. • We can automate this process with a single function:

    Embedded Pattern Matching 21 (See paper for details) match : : Matching f = > f - > f instance Matching (Exp r) instance Matching r = > Matching (Exp e - > r)
  73. • We can automate this process with a single function:

    Embedded Pattern Matching 21 (See paper for details) match : : Matching f = > f - > f instance Matching (Exp r) instance Matching r = > Matching (Exp e - > r) maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = Nothing_ - > d Just_ x - > f x \case
  74. match • We can automate this process with a single

    function: Embedded Pattern Matching 21 (See paper for details) match : : Matching f = > f - > f instance Matching (Exp r) instance Matching r = > Matching (Exp e - > r) maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = Nothing_ - > d Just_ x - > f x \case
  75. match • We can automate this process with a single

    function: Embedded Pattern Matching 21 (See paper for details) match : : Matching f = > f - > f instance Matching (Exp r) instance Matching r = > Matching (Exp e - > r) maybe : : Exp b - > (Exp a - > Exp b) - > Exp (Maybe a) - > Exp b maybe d f = Nothing_ - > d Just_ x - > f x \case
  76. Summary We demonstrate how deeply embedded languages can support user-de

    fi ned algebraic data types and can hijack pattern matching of the host language to provide pattern matching in the embedded language Trevor L. McDonell Josh Meredith Gabriele Keller tmcdonell/embedded-pattern-matching
  77. Summary We demonstrate how deeply embedded languages can support user-de

    fi ned algebraic data types and can hijack pattern matching of the host language to provide pattern matching in the embedded language Trevor L. McDonell Josh Meredith Gabriele Keller tmcdonell/embedded-pattern-matching