Friday, September 28, 2012

Pattern Matching Case Classes

  abstract class Dickmacher
  case class Beverage (name: String, cal: Int) extends Dickmacher
  case class Food (name: String, cal: Int) extends Dickmacher
  case class Meal (name: String, food: Food, drink: Beverage) extends Dickmacher
  case class Combo (starter: Dickmacher, main: Dickmacher) extends Dickmacher

  
  def drink(bev: Beverage) : Unit = {
      bev match {
          case Beverage("Kaffee", 30) => println("Zucker und Milch fehlen")
          case Beverage(_, c) if c < 50 => println("Mehr Kalorien")
          case Beverage(n, c) if c < 100 => println(n + " hat zu wenig Kalorien: " + c)
          case Beverage("Cola", 400) => println("Ahhh")
          case _ => println("Bäh!")
      }
  }
  
  def eat(bev: Meal) : Unit = {
      bev match {
          case Meal(_, Food(_, a), Beverage("Coke", b)) if a >= 400 && b >= 100 => println("Haben wollen!")
          case _ => println("Bäh!")
      }
  }
  
  println(drink(Beverage("Kaffee", 30)))
  println(drink(Beverage("Tee", 10)))
  println(drink(Beverage("Cola Light", 50)))
  println(drink(Beverage("Cola", 40)))
  println(drink(Beverage("Saft", 500)))
  
  eat(Meal("Uschi's Fried Chicken", Food("Chicken", 600), Beverage("Coke Zero", 0)))
  eat(Meal("Uschi's Fried Chicken+", Food("Chicken", 600), Beverage("Coke", 100)))

Pattern Matching Cal

  abstract class Dickmacher
  case class Beverage (name: String, cal: Int) extends Dickmacher
  case class Food (name: String, cal: Int) extends Dickmacher
  case class Meal (name: String, food: Food, drink: Beverage) extends Dickmacher
  case class Combo (starter: Dickmacher, main: Dickmacher) extends Dickmacher

  def totalCal(food: Dickmacher) : Int = food match {
    case Beverage(_, x) => x
    case Food(_, x) => x
    case Meal(_, x, y) => x.cal + y.cal
    case Combo(a: Food, b) => a.cal + totalCal(b)
    case Combo(a: Beverage, b) => a.cal + totalCal(b)
    case Combo(a: Meal, b) => totalCal(a) + totalCal(b)
    case Combo(a: Combo, b) => totalCal(a) + totalCal(b)
    case _ => throw new AssertionError();
  }
  
  val coke = Beverage("Cola Light", 50)
  val burger = Food("Big Mac", 400)
  
  val cokeLight = Beverage("Cola", 100)
  val wannaBeBurger = Food("Veggie Mac", 50)
  

  val cokeCombo = Combo(coke, cokeLight)
  println(totalCal(cokeCombo))
  
  
  val burgerCombo = Combo(burger, wannaBeBurger)
  println(totalCal(burgerCombo))
  
  
  val monsterCombo = Combo(Combo(burgerCombo, cokeCombo), Food("Nachspeise", 600));
  println(totalCal(monsterCombo))

Pattern Matching Beverages

  abstract class Dickmacher
  case class Beverage (name: String, cal: Int) extends Dickmacher
  case class Food (name: String, cal: Int) extends Dickmacher
  case class Meal (name: String, food: Food, drink: Beverage) extends Dickmacher
  case class Combo (starter: Dickmacher, main: Dickmacher) extends Dickmacher

  def countBeverages(food: Dickmacher) : Int = food match {
    case Beverage(_, x) => 1
    case Food(_, x) => 0
    case Meal(_, x, y) => 0
    case Combo(a: Food, b) => 0 + countBeverages(b)
    case Combo(a: Beverage, b) => 1 + countBeverages(b)
    case Combo(a: Meal, b) => 0 + countBeverages(b)
    case Combo(a: Combo, b) => 0 + countBeverages(b)
    case _ => throw new AssertionError();
  }
  
  val coke = Beverage("Cola Light", 50)
  val burger = Food("Big Mac", 400)
  
  
  val cokeLight = Beverage("Cola", 100)
  val wannaBeBurger = Food("Veggie Mac", 50)
  

  val cokeCombo = Combo(coke, cokeLight)
  println(countBeverages(cokeCombo))
  
  
  val burgerCombo = Combo(burger, wannaBeBurger)
  println(countBeverages(burgerCombo))
  
  
  val monsterCombo = Combo(Combo(burgerCombo, cokeCombo), Food("Nachspeise", 600));
  println(countBeverages(monsterCombo))

Pattern Matching Basics

  def matchAny(any: Any) = 
    any match {
          case "Huhu" => println("Hi")
          case 5  => println("high five");
          case a: Int  => println("Ich kann bis " + a + " zaehlen")
          case a: String  => println("Ein String")
          case (a,b) => println("Tuple mit Werten " + a + "und" + b )
          case Nil => println("Eine leere Liste")
          case List(1,2,3) => println("Liste mit den Werten 1,2,3")
          case List(a,_*) => println("Liste Laenge > 2 und  den Werten + " + a + ",*,...")
          case _ => println("Niemand passt zu: " + any)
      }
  
  
  println(matchAny("Huhu"))
  println(matchAny("5"))
  println(matchAny(10))

  class Person(name: String, weight: Int) { }
  val horst = (new Person("Horst", 55)) //compiler ignoriert fachliche Fehler
  
  println(matchAny(horst))
  println(List(horst, new Person("Anna", 105)))
  
  val desires = (horst, "Spank me!")
  println(matchAny(desires))
  
  println(matchAny(List(1,2)))
  println(matchAny(List(1,2,3)))
  println(matchAny(List(1,2,3,4,5)))