Let’s look into the pattern expressions.
Variable patterns are written as ID(sym|"x")
and WILDCARD
. They both match any value:
ID("x") // x
WILDCARD // _
Typed patterns are written as pat withType(typ|"C")
:
ID("x") withType(IntClass) // (x: Int)
WILDCARD withType(IntClass) // (_: Int)
Pattern binders are written as pat withBinder(sym|"x")
. Binders are used to give names to patterns:
WILDCARD withBinder("x") // (x @ _)
Literal patterns are written using LIT(...)
:
LIT("X") // "X"
Stable identifier patterns are written using BACKQUOTED(sym|"x")
:
BACKQUOTED("x") // `x`
Constructor patterns are written by calling UNAPPLY(pattern, ...)
to a symbol or a tree:
REF("Address") UNAPPLY(WILDCARD, WILDCARD, WILDCARD)
This prints as:
Address(_, _, _)
Tuple patterns are written using TUPLE(pattern, ...)
:
TUPLE(LIT(0), LIT(1)) // (0, 1)
Sequence wildcards are written using SEQ_WILDCARD withBinder(sym|"x")
:
REF("C") UNAPPLY(SEQ_WILDCARD withBinder("xs"))
This prints as:
C((xs @ _*))
Infix operations patterns are written by calling INFIX(op) UNAPPLY(pat, ...)
to a symbol or a tree:
LIT(0) INFIX(ConsClass) UNAPPLY (NIL)
This prints as:
0 :: Nil
Because this pattern appears frequently, treehugger DSL provides a built-in constructor UNLIST_::
:
LIT(0) UNLIST_:: NIL // 0 :: Nil
This works because an infix operation pattern p op (q, …) is a shorthand for the constructor pattern op(p, q, …).
Pattern alternatives are written as pat1 OR_PATTERN pat2
:
LIT("New York") OR_PATTERN LIT("Paris")
This prints as:
"New York" | "Paris"