Transcript
Page 1: Scala Essentials - Pattern Matching and Case Classes

CTU-FIT-SCA/scalaonfit

If you’re gonna code,download the following Gist

https://gist.github.com/ksmutny/5439360

Czech Scala Enthusiasts–April 23 2013

Scala Essentials: Pattern Matching and Case ClassesKarel Smutný–Agile Developer & Coach

Page 2: Scala Essentials - Pattern Matching and Case Classes

switch statement

switch (whatIsThis) { case 8: case 10: doSomething(); break; case 12: doSomethingElse(); break; default: doDefault();}

match expression

whatIsThis match { case 8 | 10 => something case 12 => somethingElse case _ => default}

Page 3: Scala Essentials - Pattern Matching and Case Classes

Pattern Matchinga.k.a.

Switch on steroids

Page 4: Scala Essentials - Pattern Matching and Case Classes

Pattern Matchinga.k.a.

Batman’s toolbelt

Page 5: Scala Essentials - Pattern Matching and Case Classes

https://gist.github.com/ksmutny/5439360sealed trait Character { def name: String}

case class Civilian( name: String, wealth: Wealth) extends Character

case class SuperHero( name: String, powers: List[Power], alterEgo: Option[Civilian]) extends Character

Page 6: Scala Essentials - Pattern Matching and Case Classes

The ProblemWhat are the super powers of an unknown person if it is a super hero who’s alter ego is Tony Stark?

Page 7: Scala Essentials - Pattern Matching and Case Classes

Javaif (unknownChar instanceof SuperHero) { final SuperHero hero = (SuperHero) unknownChar; if (hero.alterEgo.equals(tonyStark)) { return hero.powers; } else { return null; }} else { return null;}

Page 8: Scala Essentials - Pattern Matching and Case Classes

ScalaunknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

Page 9: Scala Essentials - Pattern Matching and Case Classes

ScalaunknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

How cool is that?

Page 10: Scala Essentials - Pattern Matching and Case Classes

JavaScript

unknownPerson.hasOwnPropery(“powers”) ? unknownPerson[“powers”] : null;

Page 11: Scala Essentials - Pattern Matching and Case Classes

Kinds of patterns

Page 12: Scala Essentials - Pattern Matching and Case Classes

Wildcard patternwhatIsThis match { case _ => “anything!”}

Page 13: Scala Essentials - Pattern Matching and Case Classes

Constant pattern

whatIsThis match { case 42 => “a magic no.” case “Hello!” => “a greeting” case math.Pi => “another magic no.” case _ => “something else”}

Page 14: Scala Essentials - Pattern Matching and Case Classes

Constant patternevaluating { BruceWayne match { case 42 => “a magic no.” case “Hello!” => “a greeting” case math.Pi => “another magic no.” }} should produce[MatchError]

Page 15: Scala Essentials - Pattern Matching and Case Classes

Variable pattern

whatIsThis match { case something => “not very useful?”}

Page 16: Scala Essentials - Pattern Matching and Case Classes

Variable pattern

whatIsThis match { case whatIsThis => “not very useful?”}

Page 17: Scala Essentials - Pattern Matching and Case Classes

Typed pattern

whatIsThis match { case n: Int => “aah, a number” case c: Character => “it’s ” + c.name}

Page 18: Scala Essentials - Pattern Matching and Case Classes

Constructor pattern

unknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

Page 19: Scala Essentials - Pattern Matching and Case Classes

Constant v Variable patternval TonyStark = Civilian(“Tony Stark”, Fortune)val BruceWayne = Civilian(“Bruce Wayne”, Fortune)val clarkKent = Civilian(“Clark Kent”, Cash(1000))

TonyStark match { case BruceWayne => “Batman!” case clarkKent => “isn’t this Superman?” case _ => “is he?”}

Page 20: Scala Essentials - Pattern Matching and Case Classes

Constant v Variable patternval TonyStark = Civilian(“Tony Stark”, Fortune)val BruceWayne = Civilian(“Bruce Wayne”, Fortune)val clarkKent = Civilian(“Clark Kent”, Cash(1000))

TonyStark match { case BruceWayne => “Batman!” case `clarkKent` => “Superman!” case _ => “anybody”}

Page 21: Scala Essentials - Pattern Matching and Case Classes

Constant v Variable patternval TonyStark = Civilian(“Tony Stark”, Fortune)val BruceWayne = Civilian(“Bruce Wayne”, Fortune)val clarkKent = Civilian(“Clark Kent”, Cash(1000))

TonyStark match { case BruceWayne => “Batman!” case `clarkKent` => “Superman!” case _ => “anybody”}

Page 22: Scala Essentials - Pattern Matching and Case Classes

Constructor patternval powers = unknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

val firstPower = powers match { case Some(power :: rest) => power case _ => Genius}

Page 23: Scala Essentials - Pattern Matching and Case Classes

Constructor patternval powers = unknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

val firstPower = powers match { case Some(power :: rest) => power case _ => Genius}

Page 24: Scala Essentials - Pattern Matching and Case Classes

Constructor patternval powers = unknownPerson match { case SuperHero(_, powers, Some(TonyStark)) => Some(powers) case _ => None}

val firstPower = powers match { case Some(power :: rest) => power case _ => Genius}

Page 25: Scala Essentials - Pattern Matching and Case Classes

Tuple patternaPair match { case (42, math.Pi, _) => “magic numbers + anything” case (IronMan, Mandarin) => “hate each other” case Tuple2(IronMan, Mandarin) => “alike” case (v: Villain, MaryJane) => “are cheating on Peter”}

Page 26: Scala Essentials - Pattern Matching and Case Classes

Sequence pattern

powers match { case List(SuperStrength, _, _*) => “at least two”}

Page 27: Scala Essentials - Pattern Matching and Case Classes

Pattern guard

aGuy match { case Civilian(_, Cash(money)) if cash >= 10000 => “Rich guy” case _ => “anybody else”}

Page 28: Scala Essentials - Pattern Matching and Case Classes

Patterns everywhere

Page 29: Scala Essentials - Pattern Matching and Case Classes

Variable definitionval (a, b) = someTupleval List(Flight, second, rest @ _*) = powersval Civilian(name, wealth: Cash) = clarkKent

Is this pattern matching, too?

val a = 3

Page 30: Scala Essentials - Pattern Matching and Case Classes

Exceptions

try { doSomethingStupid()} catch { case e: IOException => … case e: SQLException => …}

Page 31: Scala Essentials - Pattern Matching and Case Classes

Partial functionval numToStr: PartialFunction[Int, String] = { case 8 => “eight” case 10 => “ten”}

numToStr.isDefinedAt(12)

evaluating { numToStr(12)} should produce[??????????????]

Page 32: Scala Essentials - Pattern Matching and Case Classes

For comprehensionsval lines = List( “1\t2,3\t3,12”, “2\t1,3\t3,15”, “3\t1,12\t2,15”)

val edges = for { line <- lines Array(srcNode, edges @ _*) = line split “\t” edge <- edges Array(destNode, length) = edge split “,”} yield Edge(srcNode.toInt, destNode.toInt, length.toInt)

Page 33: Scala Essentials - Pattern Matching and Case Classes

For comprehensions. Beware!

val egos = for { hero : SuperHero <- characters // does not work} yield hero.alterEgo

val egos = for { hero @ (h : SuperHero) <- characters} yield hero.alterEgo

Page 34: Scala Essentials - Pattern Matching and Case Classes

Extractors

Extractors

Page 35: Scala Essentials - Pattern Matching and Case Classes

trait Person { def name: String def age: Int}

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

somePerson match { case Person(“Moses”, _) => 969 case Person(name, age) => age}

Page 36: Scala Essentials - Pattern Matching and Case Classes

trait Person { def name: String def age: Int}

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

somePerson match { case Person(“Moses”, _) => 969 case Person(name, age) => age}

Page 37: Scala Essentials - Pattern Matching and Case Classes

Case Classes

Page 38: Scala Essentials - Pattern Matching and Case Classes

No need for val in parameters

case class Villain( val name: String, val archenemy: SuperHero) extends Character

Page 39: Scala Essentials - Pattern Matching and Case Classes

No need for val in parameters

case class Villain( val name: String, val archenemy: SuperHero) extends Character

Page 40: Scala Essentials - Pattern Matching and Case Classes

No need for new keyword

new Villain(“Mandarin”, tonyStark)

object Villain { def apply(name: String, archenemy: SuperHero) = new Villain(name, archenemy)}

Page 41: Scala Essentials - Pattern Matching and Case Classes

No need for new keyword

new Villain(“Mandarin”, tonyStark)

object Villain { def apply(name: String, archenemy: SuperHero) = new Villain(name, archenemy)}

Page 42: Scala Essentials - Pattern Matching and Case Classes

No need for new keyword

new Villain(“Mandarin”, tonyStark)

object Villain { def apply(name: String, archenemy: SuperHero) = new Villain(name, archenemy)}

Page 43: Scala Essentials - Pattern Matching and Case Classes

equals and hashCodeval mandarin = Villain(“Mandarin”, tonyStark)

mandarin == Villain(“Mandarin”, tonyStark)

val villainRank = Map(mandarin -> 81)

Page 44: Scala Essentials - Pattern Matching and Case Classes

Intuitive toString

TonyStark.toString == “Civilian(Tony Stark,Fortune)”

Page 45: Scala Essentials - Pattern Matching and Case Classes

Handy copy method

val batman = SuperHero(“Batman”, List(Genius, Gadgets), Civilian(“Bruce Wayne”, Fortune))

val sixPack = batman.copy(powers = Nil)

Page 46: Scala Essentials - Pattern Matching and Case Classes

…and pattern matching

How the heck ispattern matching done

for case classes?

Page 47: Scala Essentials - Pattern Matching and Case Classes

Sealed classes

sealed trait Wealth

case class Cash(n: Int) extends Wealth

case object Fortune extends Wealth

Page 48: Scala Essentials - Pattern Matching and Case Classes

Any questions?

Page 49: Scala Essentials - Pattern Matching and Case Classes

Next meetup May 28, 2013Java 8• How does it compare to

Scala?• A closer look at λ-

expressions implementation• Influences on future

Scala versions, benefits for Scala developers

Scala 2.10• String Interpolation• Value Classes• Implicit Classes• Macros

Page 50: Scala Essentials - Pattern Matching and Case Classes

Next coding dojo–May 14, 2013


Top Related