1 // Scala Lecture 2 |
1 // Scala Lecture 2 |
2 //================= |
2 //================= |
3 |
3 |
4 |
4 // - Options |
5 // String Interpolations |
5 // - Higher-Order Functions (short-hand notation) |
6 //======================= |
6 // - maps (behind for-comprehensions) |
7 |
7 // - Pattern-Matching |
8 def cube(n: Int) : Int = n * n * n |
8 // - Recursion |
9 |
|
10 val n = 3 |
|
11 println("The cube of " + n + " is " + cube(n) + ".") |
|
12 |
|
13 println(s"The cube of $n is ${cube(n)}.") |
|
14 |
|
15 // or even |
|
16 |
|
17 println(s"The cube of $n is ${n * n * n}.") |
|
18 |
|
19 // helpful for debugging purposes |
|
20 // |
|
21 // "The most effective debugging tool is still careful |
|
22 // thought, coupled with judiciously placed print |
|
23 // statements." |
|
24 // — Brian W. Kernighan, in Unix for Beginners (1979) |
|
25 |
|
26 |
|
27 def gcd_db(a: Int, b: Int) : Int = { |
|
28 println(s"Function called with $a and $b.") |
|
29 if (b == 0) a else gcd_db(b, a % b) |
|
30 } |
|
31 |
|
32 gcd_db(48, 18) |
|
33 |
|
34 |
|
35 |
|
36 // you can also implement your own string interpolations |
|
37 |
|
38 import scala.language.implicitConversions |
|
39 import scala.language.reflectiveCalls |
|
40 |
|
41 implicit def sring_inters(sc: StringContext) = new { |
|
42 def i(args: Any*): String = s"\t${sc.s(args:_*)}\n" |
|
43 def l(args: Any*): String = s"${sc.s(args:_*)}:\n" |
|
44 } |
|
45 |
|
46 // this allows you to write things like |
|
47 |
|
48 i"add ${3+2}" |
|
49 l"some_fresh_name" |
|
50 |
|
51 |
|
52 |
9 |
53 // The Option Type |
10 // The Option Type |
54 //================= |
11 //================= |
55 |
12 |
56 // in Java, if something unusually happens, you return null |
13 // in Java, if something unusually happens, you return null |
77 if (y == 0) None else Some(x / y) |
34 if (y == 0) None else Some(x / y) |
78 |
35 |
79 safe_div(10 + 5, 4 - 1) |
36 safe_div(10 + 5, 4 - 1) |
80 |
37 |
81 List(1,2,3,4,5,6).indexOf(7) |
38 List(1,2,3,4,5,6).indexOf(7) |
|
39 List[Int]().min |
82 List[Int]().minOption |
40 List[Int]().minOption |
83 |
41 |
84 def my_min(ls: List[Int]) : Option[Int] = |
42 def my_min(ls: List[Int]) : Option[Int] = |
85 ls.minOption |
43 ls.minOption |
86 |
44 |
90 // better error handling with Options (no exceptions) |
48 // better error handling with Options (no exceptions) |
91 // |
49 // |
92 // Try(something).getOrElse(what_to_do_in_case_of_an_exception) |
50 // Try(something).getOrElse(what_to_do_in_case_of_an_exception) |
93 // |
51 // |
94 |
52 |
95 import scala.util._ |
53 import scala.util._ // Try,... |
96 import io.Source |
54 import io.Source // fromURL |
97 |
55 |
98 val my_url = "https://nms.kcl.ac.uk/christian.urban/" |
56 val my_url = "https://nms.kcl.ac.uk/christian.urban/" |
99 |
57 |
100 Source.fromURL(my_url)("ISO-8859-1").mkString |
58 Source.fromURL(my_url)("ISO-8859-1").mkString |
101 Source.fromURL(my_url)("ISO-8859-1").getLines().toList |
59 Source.fromURL(my_url)("ISO-8859-1").getLines().toList |
397 |
355 |
398 |
356 |
399 // Pattern Matching |
357 // Pattern Matching |
400 //================== |
358 //================== |
401 |
359 |
402 // A powerful tool which is supposed to come to Java in |
360 // A powerful tool which has even landed in Java during |
403 // a few years time (https://www.youtube.com/watch?v=oGll155-vuQ). |
361 // the last few years (https://inside.java/2021/06/13/podcast-017/). |
404 // ...Scala already has it for many years ;o) |
362 // ...Scala already has it for many years and the concept is |
|
363 // older than your friendly lecturer, that is stone old ;o) |
405 |
364 |
406 // The general schema: |
365 // The general schema: |
407 // |
366 // |
408 // expression match { |
367 // expression match { |
409 // case pattern1 => expression1 |
368 // case pattern1 => expression1 |
418 lst match { |
377 lst match { |
419 case Nil => Nil |
378 case Nil => Nil |
420 case x::xs => f(x)::my_map_int(xs, f) |
379 case x::xs => f(x)::my_map_int(xs, f) |
421 } |
380 } |
422 |
381 |
423 def my_map_option(o: Option[Int], f: Int => Int) : Option[Int] = |
382 def my_map_option(opt: Option[Int], f: Int => Int) : Option[Int] = |
424 o match { |
383 opt match { |
425 case None => None |
384 case None => None |
426 case Some(x) => Some(f(x)) |
385 case Some(x) => Some(f(x)) |
427 } |
386 } |
428 |
387 |
429 my_map_option(None, x => x * x) |
388 my_map_option(None, x => x * x) |