1 // Scala Lecture 2 |
1 // Scala Lecture 2 |
2 //================= |
2 //================= |
3 |
3 |
4 |
4 |
|
5 |
5 // Option type |
6 // Option type |
6 //============= |
7 //============= |
|
8 |
|
9 //in Java if something unusually happens, you return null |
|
10 //in Scala you use Option |
|
11 // - if the value is present, you use Some(value) |
|
12 // - if no value is present, you use None |
|
13 |
|
14 |
|
15 List(7,2,3,4,5,6).find(_ < 4) |
|
16 List(5,6,7,8,9).find(_ < 4) |
|
17 |
7 val lst = List(None, Some(1), Some(2), None, Some(3)) |
18 val lst = List(None, Some(1), Some(2), None, Some(3)) |
8 |
19 |
9 lst.flatten |
20 lst.flatten |
|
21 |
10 Some(1).get |
22 Some(1).get |
|
23 |
|
24 Some(1).isDefined |
|
25 None.isDefined |
11 |
26 |
12 val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1)) |
27 val ps = List((3, 0), (3, 2), (4, 2), (2, 0), (1, 0), (1, 1)) |
13 |
28 |
14 for ((x, y) <- ps) yield { |
29 for ((x, y) <- ps) yield { |
15 if (y == 0) None else Some(x / y) |
30 if (y == 0) None else Some(x / y) |
16 } |
31 } |
17 |
32 |
18 // sudoku |
33 // getOrElse is to set a default value |
19 // some none |
34 |
20 // pattern matching |
35 val lst = List(None, Some(1), Some(2), None, Some(3)) |
21 |
36 for (x <- lst) yield x getOrElse 0 |
22 //type abbreviations |
37 |
|
38 |
|
39 import scala.util._ |
|
40 import io.Source |
|
41 // error handling with option |
|
42 // |
|
43 // Try(something).getOrElse(what_to_do_in_an_exception) |
|
44 |
|
45 Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanccc/""").mkString |
|
46 |
|
47 Try(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString).getOrElse("") |
|
48 |
|
49 Try(Some(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString)).getOrElse(None) |
|
50 |
|
51 |
|
52 Integer.parseInt("12u34") |
|
53 |
|
54 def get_me_an_int(s: String): Option[Int] = |
|
55 Try(Some(Integer.parseInt(s))).getOrElse(None) |
|
56 |
|
57 val lst = List("12345", "foo", "5432", "bar", "x21") |
|
58 for (x <- lst) yield get_me_an_int(x) |
|
59 |
|
60 // summing all the numbers |
|
61 val sum = lst.flatMap(get_me_an_int(_)).sum |
|
62 |
|
63 |
|
64 // This may not look any better than working with null in Java, but to |
|
65 // see the value, you have to put yourself in the shoes of the |
|
66 // consumer of the get_me_an_int function, and imagine you didn't |
|
67 // write that function. |
|
68 // |
|
69 // In Java, if you didn't write this function, you'd have to depend on |
|
70 // the Javadoc of the get_me_an_int. If you didn't look at the Javadoc |
|
71 // for the Java, you might not know that get_me_an_int could return a |
|
72 // null, and your code could potentially throw a NullPointerException. |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 // Type abbreviations |
|
79 //==================== |
|
80 |
|
81 // some syntactic convenience |
23 type Pos = (int, Int) |
82 type Pos = (int, Int) |
|
83 |
|
84 type Board = List[List[Int]] |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 // No return in Scala |
|
90 //==================== |
|
91 |
|
92 //You should not use "return" in Scala: |
|
93 // |
|
94 // A return expression, when evaluated, abandons the |
|
95 // current computation and returns to the caller of the |
|
96 // function in which return appears." |
|
97 |
|
98 def sq1(x: Int): Int = x * x |
|
99 def sq2(x: Int): Int = return x * x |
|
100 |
|
101 def sumq(ls: List[Int]): Int = { |
|
102 (for (x <- ls) yield (return x * x)).sum[Int] |
|
103 } |
|
104 |
|
105 sumq(List(1,2,3,4)) |
|
106 |
|
107 // last expression in a function is the return statement |
|
108 def square(x: Int): Int = { |
|
109 println(s"The argument is ${x}.") |
|
110 x * x |
|
111 } |
|
112 |
|
113 // Pattern Matching |
|
114 //================== |
|
115 |
|
116 // A powerful tool which is supposed to come to Java in a few years |
|
117 // time (https://www.youtube.com/watch?v=oGll155-vuQ)...Scala already |
|
118 // has it for many years ;o) |
|
119 |
|
120 // The general schema: |
|
121 // |
|
122 // expression match { |
|
123 // case pattern1 => expression1 |
|
124 // case pattern2 => expression2 |
|
125 // ... |
|
126 // case patternN => expressionN |
|
127 // } |
|
128 |
|
129 |
|
130 // remember |
|
131 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten |
|
132 |
|
133 |
|
134 def my_flatten(xs: List[Option[Int]]): List[Int] = { |
|
135 ... |
|
136 } |
|
137 |
|
138 |
|
139 def my_flatten(lst: List[Option[Int]]): List[Int] = lst match { |
|
140 case Nil => Nil |
|
141 case None::xs => my_flatten(xs) |
|
142 case Some(n)::xs => n::my_flatten(xs) |
|
143 } |
|
144 |
|
145 |
|
146 // another example |
|
147 def get_me_a_string(n: Int): String = n match { |
|
148 case 0 => "zero" |
|
149 case 1 => "one" |
|
150 case 2 => "two" |
|
151 case _ => "many" |
|
152 } |
|
153 |
|
154 |
|
155 // Higher-Order Functions |
|
156 //======================== |
|
157 |
|
158 // functions can take functions as arguments |
|
159 |
|
160 val lst = (1 to 10).toList |
|
161 |
|
162 def even(x: Int): Boolean = x % 2 == 0 |
|
163 def odd(x: Int): Boolean = x % 2 == 1 |
|
164 |
|
165 lst.filter(x => even(x)) |
|
166 lst.filter(even(_)) |
|
167 lst.filter(even) |
|
168 |
|
169 lst.find(_ > 8) |
|
170 |
|
171 def square(x: Int): Int = x * x |
|
172 |
|
173 lst.map(square) |
|
174 |
|
175 lst.map(square).filter(_ > 4) |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 // Sudoku |
|
181 //======== |
|
182 |
|
183 |
|
184 |
|
185 |
24 |
186 |
25 //sorting, higher-order functions |
187 //sorting, higher-order functions |
26 //lexicographic ordering |
188 //lexicographic ordering |
27 |
189 |
28 |
190 |