progs/lecture2.scala
changeset 365 fc118ee0fce4
parent 364 f1a6fa599d26
child 366 1c829680503e
equal deleted inserted replaced
364:f1a6fa599d26 365:fc118ee0fce4
   390 
   390 
   391 
   391 
   392 // Pattern Matching
   392 // Pattern Matching
   393 //==================
   393 //==================
   394 
   394 
   395 // A powerful tool which is supposed to come to Java in a few years
   395 // A powerful tool which is supposed to come to Java in 
   396 // time (https://www.youtube.com/watch?v=oGll155-vuQ)...Scala already
   396 // a few years time (https://www.youtube.com/watch?v=oGll155-vuQ).
   397 // has it for many years ;o)
   397 // ...Scala already has it for many years ;o)
   398 
   398 
   399 // The general schema:
   399 // The general schema:
   400 //
   400 //
   401 //    expression match {
   401 //    expression match {
   402 //       case pattern1 => expression1
   402 //       case pattern1 => expression1
   405 //       case patternN => expressionN
   405 //       case patternN => expressionN
   406 //    }
   406 //    }
   407 
   407 
   408 
   408 
   409 // recall
   409 // recall
   410 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
   410 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = 
   411 
   411   lst match {
   412 def my_flatten(xs: List[Option[Int]]): List[Int] = 
   412     case Nil => Nil
   413 xs match {
   413     case x::xs => f(x)::my_map_int(xs, f)
   414   case Nil => Nil 
   414   }
   415   case None::rest => my_flatten(rest)
   415 
   416   case Some(v)::rest => v :: my_flatten(rest)
   416 def my_map_option(o: Option[Int], f: Int => Int) : Option[Int] = 
   417 }
   417   o match {
   418 
   418     case None => None
   419 my_flatten(List(None, Some(1), Some(2), None, Some(3)))
   419     case Some(x) => Some(f(x))
   420 
   420   }
   421 
   421 
   422 // another example with a default case
   422 my_map_option(None, x => x * x)
   423 def get_me_a_string(n: Int): String = n match {
   423 my_map_option(Some(8), x => x * x)
   424   case 0 | 1 | 2 => "small"
       
   425 }
       
   426 
       
   427 get_me_a_string(3)
       
   428 
   424 
   429 
   425 
   430 // you can also have cases combined
   426 // you can also have cases combined
   431 def season(month: String) : String = month match {
   427 def season(month: String) : String = month match {
   432   case "March" | "April" | "May" => "It's spring"
   428   case "March" | "April" | "May" => "It's spring"
   433   case "June" | "July" | "August" => "It's summer"
   429   case "June" | "July" | "August" => "It's summer"
   434   case "September" | "October" | "November" => "It's autumn"
   430   case "September" | "October" | "November" => "It's autumn"
   435   case "December" => "It's winter"
   431   case "December" => "It's winter"
   436   case "January" | "February" => "It's unfortunately winter"
   432   case "January" | "February" => "It's unfortunately winter"
   437 }
   433   case _ => "Wrong month"
   438  
   434 }
   439 println(season("November"))
   435 
   440 
   436 // pattern-match on integers
   441 // What happens if no case matches?
   437 
   442 println(season("foobar"))
   438 def fib(n: Int) : Int = n match { 
   443 
   439   case 0 | 1 => 1
   444 
   440   case n => fib(n - 1) + fib(n - 2)
   445 // days of some months
   441 }
   446 def days(month: String) : Int = month match {
   442 
   447   case "March" | "April" | "May" => 31
   443 fib(10)
   448   case "June" | "July" | "August" => 30
       
   449 }
       
   450 
       
   451 
   444 
   452 // Silly: fizz buzz
   445 // Silly: fizz buzz
   453 def fizz_buzz(n: Int) : String = (n % 3, n % 5) match {
   446 def fizz_buzz(n: Int) : String = (n % 3, n % 5) match {
   454   case (0, 0) => "fizz buzz"
   447   case (0, 0) => "fizz buzz"
   455   case (0, _) => "fizz"
   448   case (0, _) => "fizz"
   456   case (_, 0) => "buzz"
   449   case (_, 0) => "buzz"
   457   case _ => n.toString  
   450   case _ => n.toString  
   458 }
   451 }
   459 
   452 
   460 for (n <- 0 to 20) 
   453 for (n <- 1 to 20) 
   461  println(fizz_buzz(n))
   454  println(fizz_buzz(n))
       
   455 
       
   456 
       
   457 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten
       
   458 
       
   459 def my_flatten(xs: List[Option[Int]]): List[Int] = 
       
   460  xs match {
       
   461    case Nil => Nil 
       
   462    case None::rest => my_flatten(rest)
       
   463    case Some(v)::rest => v :: my_flatten(rest)
       
   464  }
       
   465 
       
   466 my_flatten(List(None, Some(1), Some(2), None, Some(3)))
       
   467 
       
   468 
       
   469 
       
   470  
   462 
   471 
   463 
   472 
   464 
   473 
   465 
   474 
   466 // Recursion
   475 // Recursion
   467 //===========
   476 //===========
   468 
       
   469 // well-known example
       
   470 
       
   471 def fib(n: Int) : Int = { 
       
   472   if (n == 0 || n == 1) 1
       
   473    else fib(n - 1) + fib(n - 2)
       
   474 }
       
   475 
   477 
   476 
   478 
   477 /* Say you have characters a, b, c.
   479 /* Say you have characters a, b, c.
   478    What are all the combinations of a certain length?
   480    What are all the combinations of a certain length?
   479 
   481