scala essentials - pattern matching and case classes

50
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 Classes Karel Smutný–Agile Developer & Coach

Upload: czech-scala-enthusiasts

Post on 01-Sep-2014

4.718 views

Category:

Technology


0 download

DESCRIPTION

In-depth presentation about basics of pattern matching and case classes given by Karel Smutný at the April's Czech Scala Enthusiasts meetup held at Faculty of Information Technology in Prague.

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