progs/lecture2.scala
changeset 155 371acb50643d
parent 150 9a2f2a1de42b
child 167 349d706586ef
equal deleted inserted replaced
154:39c6b93718f0 155:371acb50643d
   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 //====================