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. Embedded Pattern Matching
    Trevor L. McDonell
    Joshua D. Meredith
    Gabriele Keller

    View Slide

  2. Algebraic data types
    data List a = Nil


    | Cons a (List a)
    2

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

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


    . . .

    View Slide

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


    . . .

    View Slide

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


    . . .

    View Slide

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


    length’ =
    . . .
    ?
    4

    View Slide

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


    length’ =
    . . .
    ?
    4

    View Slide

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

    View Slide

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

    View Slide

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


    | ^

    View Slide

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

    View Slide

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

    View Slide

  16. 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 =
    . . .
    ?

    View Slide

  17. Ingredient #1:


    Expression language
    10

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. Embedding Point
    12
    data Point = Point F
    l
    oat F
    l
    oat

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    Representation type (closed)
    Surface type (extensible)

    View Slide

  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
    Representation type (closed)
    Surface type (extensible)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  32. Ingredient #2:


    Pattern synonyms
    13

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  37. 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 =
    . . .
    ?


    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  46. Ingredient #3:


    match
    16

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  52. Embedding Maybe
    19
    data Maybe a = Nothing | Just a

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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
    Tag
    Fields of Nothing
    Fields of Just

    View Slide

  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)
    Tag
    Fields of Nothing
    Fields of Just

    View Slide

  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)
    Tag
    Fields of Nothing
    Fields of Just

    View Slide

  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)
    Tag
    Fields of Nothing
    Fields of Just

    View Slide

  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)
    Tag
    Fields of Nothing
    Fields of Just

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  67. 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 a
    - >
    Just ( Prj
    . . .
    a )
    Tag
    Fields of Nothing
    Fields of Just
    Embedded

    expression
    Regular Haskell value!
    Embedded expression

    to extract the value

    View Slide

  68. 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 a
    - >
    Just ( Prj
    . . .
    a )
    Tag
    Fields of Nothing
    Fields of Just
    Embedded

    expression
    Regular Haskell value!
    Embedded expression

    to extract the value

    View Slide

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

    View Slide

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

    View Slide

  71. 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  72. 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  73. 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  74. Key idea
    • We need to evaluate this function twice
    - Match is the dummy argument consumed by the embedded pattern synonym
    - The 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  75. Key idea
    • We need to evaluate this function twice
    - Match is the dummy argument consumed by the embedded pattern synonym
    - The 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  76. Key idea
    • We need to evaluate this function twice
    - Match is the dummy argument consumed by the embedded pattern synonym
    - The 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  77. Key idea
    • We need to evaluate this function twice
    - Match is the dummy argument consumed by the embedded pattern synonym
    - The 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

  78. Key idea
    • We need to evaluate this function twice
    - Match is the dummy argument consumed by the embedded pattern synonym
    - The 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 p)


    rhs_just = maybe d f (Match p)


    in


    Case p [ (, rhs_nothing)


    , (, rhs_just)


    ]

    View Slide

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

    View Slide

  80. • 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)

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide