Some languages, like SML, Haskell, and Scala, have built-in support for pattern matching, which is a generic way of branching based on the structure of data.
While not without its drawbacks, pattern matching can help eliminate a lot of boilerplate, and it's often cited as a reason why functional programming languages are so concise.
In this talk, John A. De Goes talks about the differences between built-in patterns, and so-called first-class patterns (which are "do-it-yourself" patterns implemented using other language features).
Unlike built-in patterns, first-class patterns aren't magical, so you can store them in variables and combine them in lots of interesting ways that aren't always possible with built-in patterns. In addition, almost every programming language can support first-class patterns (albeit with differing levels of effort and type-safety).
During the talk, you'll watch as a mini-pattern matching library is developed, and have the opportunity to follow along and build your own pattern matching library in the language of your choice.
3. Intro
Pattern Matching
● Divides a (possibly infinite) set of values into
a discrete number of cases, where each case
can be handled in a uniform way
● “if” on steroids
○ Sometimes strictly more powerful (e.g. Haskell)
4. Intro - Examples
-- sign of a number
sign x |
|
|
x > 0
x == 0
x < 0
=
=
=
1
0
-1
-- take the first n elements from a list
take
take
take
0
_
n
_
[]
(x:xs)
=
=
=
[]
[]
x : take (n-1) xs
-- generate some javascript
valueToJs
valueToJs
valueToJs
valueToJs
...
:: Options -> ModuleName -> Environment -> Value -> JS
_ _ _ (NumericLiteral n) = JSNumericLiteral n
_ _ _ (StringLiteral s) = JSStringLiteral s
_ _ _ (BooleanLiteral b) = JSBooleanLiteral b
5. Intro - Examples
sealed trait Level
case object Level1 extends Level
case object Level2 extends Level
sealed trait Title
case object DBAdmin extends Title
case class SWEngineer(level: Level) extends Title
case class Employee(manager: Option[Employee], name: String, title: Title)
val employees = ???
val selfManagedLevel2Engineers = employees.collect {
case Employee(None, name, SWEngineer(Level2)) => name
}
6. Pattern Matching 101
Filter
Does it have the structure I
want? [Yes/No]
If so, extract out the pieces
that are relevant to me.
Extract
7. Pattern Matching 101
-- take the first n elements from a list
take 0
_
= []
take _
[]
= []
take n
(x:xs)
= x : take (n-1) xs
Filter - does it have non-empty list structure?
Extract - Give me ‘head’ and ‘tail’
8. Pattern Matching 101
Products
Sums
case class Employee(
sealed trait Title
manager: Option[Employee],
name:
String,
title:
case object DBAdmin extends Title
terms
Title
case class SWEngineer(level: Level)
extends Title
)
class Account {
interface Shape { }
...
class Rect extends Shape { … }
public Account(BigDecimal balance, User holder) {
class Ellipse extends Shape { … }
...
}
}
class Pentagon extends Shape { … }
terms
9. First-Class-ness 101
data Maybe a = Nothing | Just a deriving (Eq, Ord)
class Person {
public Person(String name, int age) {
...
}
}
18. First-Class Patterns
Haskell Example
ex4 :: Either (Int,Int) Int -> Int
ex4 a = match a $
(1+) <$> (left (pair var (cst 4)) ->> id
<|>
right var
->> id)
<|> left (pair __ var) ->> id
http://hackage.haskell.org/package/first-class-patterns
24. First-Class Patterns
Limitations
● Extractors cannot throw away information,
leading to ‘dummy parameters’
● Negation not possible under any
circumstances
● No partiality warnings or built-in catch all
25. Exercises
1. Define a Pattern Combinator to Fix:
val Add = Mapping(
"(+)", "Adds two numeric values" NumericDomain,
,
(partialTyper {
case Type.Const(Data.Number(v1)) :: v2 :: Nil if (v1.signum == 0) => v2
case v1 :: Type.Const(Data.Number(v2)) :: Nil if (v2.signum == 0) => v1
case Type.Const(Data.
Int(v1)) :: Type.Const(Data.
Int(v2)) :: Nil =>
Type.Const(Data.
Int(v1 + v2))
case Type.Const(Data.Number(v1)) :: Type.Const(Data.Number(v2)) ::
Nil =>
Type.Const(Data.Dec(v1 + v2))
}) ||| numericWidening
)
EASY
28. Exercises
4. Define an alternate definition of
pattern (along with a few core patterns)
that permits pattern negation
4.b Optional: Use this to allow catch-alls
MODERATE
29. Exercises
5. Define an alternate definition of
pattern (along with a few core patterns)
that permits extractors to throw away
information
HARD