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 //==================== |