Beauty of Pattern Matching

20
Beauty of pattern matching in Scala Karel Smutný Czech Scala Enthusiast 1 st meet-up, September 20, 2011

description

First presentation at the Czech Scala Enthusiasts meetup on September 20, 2011.

Transcript of Beauty of Pattern Matching

Page 1: Beauty of Pattern Matching

Beauty of pattern matching in ScalaKarel Smutný

Czech Scala Enthusiast1st meet-up, September 20, 2011

Page 2: Beauty of Pattern Matching

Agenda• Scala match expression v Java switch• What is pattern matching• Pattern types• Extractors• Other uses

▫ Variables declaration▫ for expressions▫ catch clauses▫ Regular expressions▫ XML

• Pattern matching v Visitor Pattern

Page 3: Beauty of Pattern Matching

Scala match v Java switchmatch switchsomeFlag match {

case 1 | 2 => doSomething()

case 3 => doSomethingElse()

case _ => doSomethingDefault()

}

switch (someFlag) {case 1:case 2:

doSomething();break;

case 3:doSomethingElse();break;

default:doSomethingDefault();

}

Page 4: Beauty of Pattern Matching

Scala match v Java switchmatch switch• Expression• Returns value of the first

matched alternative• Much, much, much more

powerful

• Statement• Pesky break keyword• Only some primitive types,

String and enum, only literals/constants

Page 5: Beauty of Pattern Matching

What is pattern matching?•Wiki:

“…pattern matching is the act of checking some sequence of tokens for the presence of the constituents of some pattern.”

Page 6: Beauty of Pattern Matching

Wildcard patternobj match {case _ => ...

}

•Matches anything•Used as a default; if not present, compiler

emits a warning

Page 7: Beauty of Pattern Matching

Variable patternobj match {case anotherName => ...

}

•Matches anything, creates new variable•Uses type inference

Page 8: Beauty of Pattern Matching

Type patternobj match {case str: String => …

}

if ((obj instanceof String) && (obj != null)) {String str = (String) obj;…

}

Page 9: Beauty of Pattern Matching

Constant patternobj match {case 4 => …case DasObject => …case `existingVariable` => …

}

•Matches exact value, in terms of ==

Page 10: Beauty of Pattern Matching

Tuple patternobj match {case (4, _, “some text”) => …case (a: Int, b: Double) => …

}

•Matches if obj is proper TupleX and all its fields match

Page 11: Beauty of Pattern Matching

Constructor patterncase class Person(name: String, age: Int)

obj match {case Person(_, 25) => …case Person(“Jarda”, age) => …case Person(_, age) if age >= 18 => …

}

• Matches if value.isInstance[Person] and appropriate attributes match (imagine this in Java)

• Works only for case classes (does it?)

Page 12: Beauty of Pattern Matching

Sequence patternobj match {case List(_, 2, x) => …case List(1, 2, 3, _*) => …case head :: tail => …

}

• Matches variable number of arguments (vararg)• _* matches any number of other arguments,

including none

Page 13: Beauty of Pattern Matching

Extractor• What about non-case classes?

class Person(val name: String, val age: Int)object Person { def unapply(p: Person): Option[(String, Int)] = Some(p.name, p.age)}

obj match {case Person(_, 25) => …case Person(“Jarda”, age) => …case Person(_, age) if age >= 18 => …

}

Page 14: Beauty of Pattern Matching

Other types of extractors• Sequence pattern matching

def unapplySeq(a: SomeClass): Option[Seq[?]]

• One argument only (there is no Tuple1)def unapply(a: SomeClass): Option[Int]

• Note the parentheses (otherwise it would be constant pattern)def unapply(a: SomeClass): Boolean

value match {case SomeClass() => …

}

Page 15: Beauty of Pattern Matching

Other uses: Variable declaration• You may use pattern matching to declare variables:

val (a, b, c) = (5, “text”, someFunction)val (a, _) = (5, “to be forgotten forever”)val Person(name, age) = somePerson

• Geez! Look at this. It’s a pattern matching!

val a = 5

Page 16: Beauty of Pattern Matching

Other uses: for expression• You may use pattern matching in for

expressions:

val personList: List[Person] = ...for (Person(name, age) <- personList) ...

• Don’t forget unapply() on iterated elements

Page 17: Beauty of Pattern Matching

Other uses: catch clause• This is pattern matching, too:

try { doSomethingStupid()}catch { case e: IllegalArgumentException => ... case SomeCustomException(someDetail) => ... case _ => ...}

Page 18: Beauty of Pattern Matching

Other uses: Regular expressions• Guess where is the unapply() method:

val person = “““^(\w)+,(\d)+$”””.rsomeInput match { case person(name, age) => ...}

• Here it is:

class Regex { def unapplySeq(target: Any): Option[List[String]]}

Page 19: Beauty of Pattern Matching

Other uses: XML• Just a teaser (XML pattern matching is out of scope of this

talk):

catalog match { case <catalog>{therms @ _*}</catalog> => for (therm @ <cctherm>{_*}</cctherm> <- therms) ...}

Page 20: Beauty of Pattern Matching

Topic for discussion: Visitor pattern