54

# Embedded Pattern Matching

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

## Transcript

1. Embedded Pattern Matching
Trevor L. McDonell
Joshua D. Meredith
Gabriele Keller

2. Algebraic data types
data List a = Nil

| Cons a (List a)
2

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

4. Embedded languages
data Exp a where

Lit
: :
Int
- >
Exp Int

Succ
: :
Exp Int
- >
Exp Int

. . .
3

5. ans
: :
Exp Int

ans = Succ (Lit 41)
Embedded languages
data Exp a where

Lit
: :
Int
- >
Exp Int

Succ
: :
Exp Int
- >
Exp Int

. . .
3

6. ans
: :
Exp Int

ans = Succ (Lit 41)
Embedded languages
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

. . .

7. ans
: :
Exp Int

ans = Succ (Lit 41)
Embedded languages
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

. . .

8. ans
: :
Exp Int

ans = Succ (Lit 41)
Embedded languages
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

. . .

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

length’ =
. . .
?
4

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

length’ =
. . .
?
4

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/

12. Option 1: Lots of type errors
• De
fi
ne functions to “push” a constructor through an expression
6
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

13. Option 1: Lots of type errors
• De
fi
ne functions to “push” a constructor through an expression
6
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

| ^

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

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

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

17. Ingredient #1:

Expression language
10

18. Grammar
• A minimal expression language

- Variables, application, abstraction, etc. are standard
- 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

19. Grammar
• A minimal expression language

- Variables, application, abstraction, etc. are standard
- 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

20. Grammar
• A minimal expression language

- Variables, application, abstraction, etc. are standard
- 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

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

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

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

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)

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)

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)

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)

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)

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)

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)

embedded expressions

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)

embedded expressions

new embedded terms

32. Ingredient #2:

Pattern synonyms
13

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

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

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

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)

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

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

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!

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!

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!

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!

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!

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!

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!

46. Ingredient #3:

match
16

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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
Embedded expression

to extract the value

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
Embedded expression

to extract the value

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
Embedded expression

to extract the value

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
Embedded expression

to extract the value

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

match should succeed
Embedded expression

to extract the value

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

match should succeed
Embedded expression

to extract the value

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)

]

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)

]

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)

]

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)

]

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)

]

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)

]

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)

]

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)

]

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

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)

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

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

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

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

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