342 better_first_word("Hello World").map(duplicate) | 
   342 better_first_word("Hello World").map(duplicate) | 
   343 better_first_word("").map(duplicate).map(duplicate).map(valid_msg) | 
   343 better_first_word("").map(duplicate).map(duplicate).map(valid_msg) | 
   344   | 
   344   | 
   345 better_first_word("").map(duplicate) | 
   345 better_first_word("").map(duplicate) | 
   346 better_first_word("").map(duplicate).map(valid_msg) | 
   346 better_first_word("").map(duplicate).map(valid_msg) | 
   347   | 
         | 
   348   | 
         | 
   349 // Pattern Matching  | 
         | 
   350 //==================  | 
         | 
   351   | 
         | 
   352 // A powerful tool which is supposed to come to Java in a few years  | 
         | 
   353 // time (https://www.youtube.com/watch?v=oGll155-vuQ)...Scala already  | 
         | 
   354 // has it for many years ;o)  | 
         | 
   355   | 
         | 
   356 // The general schema:  | 
         | 
   357 //  | 
         | 
   358 //    expression match { | 
         | 
   359 //       case pattern1 => expression1  | 
         | 
   360 //       case pattern2 => expression2  | 
         | 
   361 //       ...  | 
         | 
   362 //       case patternN => expressionN  | 
         | 
   363 //    }  | 
         | 
   364   | 
         | 
   365   | 
         | 
   366 // remember  | 
         | 
   367 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten  | 
         | 
   368   | 
         | 
   369   | 
         | 
   370 def my_flatten(xs: List[Option[Int]]): List[Int] = { | 
         | 
   371   ...?  | 
         | 
   372 }  | 
         | 
   373   | 
         | 
   374   | 
         | 
   375   | 
         | 
   376   | 
         | 
   377   | 
         | 
   378 def my_flatten(lst: List[Option[Int]]): List[Int] = lst match { | 
         | 
   379   case Nil => Nil  | 
         | 
   380   case None::xs => my_flatten(xs)  | 
         | 
   381   case Some(n)::xs => n::my_flatten(xs)  | 
         | 
   382 }  | 
         | 
   383   | 
         | 
   384   | 
         | 
   385 // another example including a catch-all pattern  | 
         | 
   386 def get_me_a_string(n: Int): String = n match { | 
         | 
   387   case 0 => "zero"  | 
         | 
   388   case 1 => "one"  | 
         | 
   389   case 2 => "two"  | 
         | 
   390   case _ => "many"  | 
         | 
   391 }  | 
         | 
   392   | 
         | 
   393 get_me_a_string(0)  | 
         | 
   394   | 
         | 
   395 // you can also have cases combined  | 
         | 
   396 def season(month: String) = month match { | 
         | 
   397   case "March" | "April" | "May" => "It's spring"  | 
         | 
   398   case "June" | "July" | "August" => "It's summer"  | 
         | 
   399   case "September" | "October" | "November" => "It's autumn"  | 
         | 
   400   case "December" | "January" | "February" => "It's winter"  | 
         | 
   401 }  | 
         | 
   402    | 
         | 
   403 println(season("November")) | 
         | 
   404   | 
         | 
   405 // What happens if no case matches?  | 
         | 
   406   | 
         | 
   407 println(season("foobar")) | 
         | 
   408   | 
         | 
   409   | 
         | 
   410 // User-defined Datatypes  | 
         | 
   411 //========================  | 
         | 
   412   | 
         | 
   413 abstract class Colour  | 
         | 
   414 case class Red() extends Colour   | 
         | 
   415 case class Green() extends Colour   | 
         | 
   416 case class Blue() extends Colour  | 
         | 
   417   | 
         | 
   418 def fav_colour(c: Colour) : Boolean = c match { | 
         | 
   419   case Red()   => false  | 
         | 
   420   case Green() => true  | 
         | 
   421   case Blue()  => false   | 
         | 
   422 }  | 
         | 
   423   | 
         | 
   424   | 
         | 
   425 // actually colors can be written with "object",  | 
         | 
   426 // because they do not take any arguments  | 
         | 
   427   | 
         | 
   428   | 
         | 
   429 // another example  | 
         | 
   430 //=================  | 
         | 
   431   | 
         | 
   432 // Once upon a time, in a complete fictional country there were persons...  | 
         | 
   433   | 
         | 
   434 abstract class Person  | 
         | 
   435 case class King() extends Person  | 
         | 
   436 case class Peer(deg: String, terr: String, succ: Int) extends Person  | 
         | 
   437 case class Knight(name: String) extends Person  | 
         | 
   438 case class Peasant(name: String) extends Person  | 
         | 
   439   | 
         | 
   440   | 
         | 
   441 def title(p: Person): String = p match { | 
         | 
   442   case King() => "His Majesty the King"  | 
         | 
   443   case Peer(deg, terr, _) => s"The ${deg} of ${terr}" | 
         | 
   444   case Knight(name) => s"Sir ${name}" | 
         | 
   445   case Peasant(name) => name  | 
         | 
   446 }  | 
         | 
   447   | 
         | 
   448   | 
         | 
   449 def superior(p1: Person, p2: Person): Boolean = (p1, p2) match { | 
         | 
   450   case (King(), _) => true  | 
         | 
   451   case (Peer(_,_,_), Knight(_)) => true  | 
         | 
   452   case (Peer(_,_,_), Peasant(_)) => true  | 
         | 
   453   case (Peer(_,_,_), Clown()) => true  | 
         | 
   454   case (Knight(_), Peasant(_)) => true  | 
         | 
   455   case (Knight(_), Clown()) => true  | 
         | 
   456   case (Clown(), Peasant(_)) => true  | 
         | 
   457   case _ => false  | 
         | 
   458 }  | 
         | 
   459   | 
         | 
   460 val people = List(Knight("David"),  | 
         | 
   461                   Peer("Duke", "Norfolk", 84),  | 
         | 
   462                   Peasant("Christian"),  | 
         | 
   463                   King(),   | 
         | 
   464                   Clown())  | 
         | 
   465   | 
         | 
   466 println(people.sortWith(superior(_, _)).mkString(", ")) | 
         | 
   467   | 
   347   | 
   468   | 
   348   | 
   469   | 
   349   | 
   470   | 
   350   | 
   471   | 
   351   | 
   507   | 
   387   | 
   508 time_needed(10, count_intersection(A, B))  | 
   388 time_needed(10, count_intersection(A, B))  | 
   509 time_needed(10, count_intersection2(A, B))  | 
   389 time_needed(10, count_intersection2(A, B))  | 
   510   | 
   390   | 
   511   | 
   391   | 
   512 // Implicits (Cool Feature)  | 
   392   | 
   513 //=========================  | 
         | 
   514 //  | 
         | 
   515 // For example adding your own methods to Strings:  | 
         | 
   516 // Imagine you want to increment strings, like  | 
         | 
   517 //  | 
         | 
   518 //     "HAL".increment  | 
         | 
   519 //  | 
         | 
   520 // you can avoid ugly fudges, like a MyString, by  | 
         | 
   521 // using implicit conversions.  | 
         | 
   522   | 
         | 
   523   | 
         | 
   524 implicit class MyString(s: String) { | 
         | 
   525   def increment = for (c <- s) yield (c + 1).toChar   | 
         | 
   526 }  | 
         | 
   527   | 
         | 
   528 "HAL".increment  | 
         | 
   529   | 
   393   | 
   530   | 
   394   | 
   531   | 
   395   | 
   532 // No returns in Scala  | 
   396 // No returns in Scala  | 
   533 //====================  | 
   397 //====================  |