|     59 get_contents("text.txt") |     91 get_contents("text.txt") | 
|     60 get_contents("test.txt") |     92 get_contents("test.txt") | 
|     61  |     93  | 
|     62  |     94  | 
|     63  |     95  | 
|     64 // For-Comprehensions Again |         | 
|     65 //========================== |         | 
|     66  |         | 
|     67 // the first produces a result, while the second does not |         | 
|     68 for (n <- List(1, 2, 3, 4, 5)) yield n * n |         | 
|     69  |         | 
|     70  |         | 
|     71 for (n <- List(1, 2, 3, 4, 5)) println(n) |         | 
|     72  |         | 
|     73  |         | 
|     74 // String Interpolations |         | 
|     75 //======================= |         | 
|     76  |         | 
|     77 val n = 3 |         | 
|     78 println("The square of " + n + " is " + square(n) + ".") |         | 
|     79  |         | 
|     80 println(s"The square of ${n} is ${square(n)}.") |         | 
|     81  |         | 
|     82  |         | 
|     83 // helpful for debugging purposes |         | 
|     84 // |         | 
|     85 //         "The most effective debugging tool is still careful thought,  |         | 
|     86 //          coupled with judiciously placed print statements." |         | 
|     87 //                   — Brian W. Kernighan, in Unix for Beginners (1979) |         | 
|     88  |         | 
|     89  |         | 
|     90 def gcd_db(a: Int, b: Int) : Int = { |         | 
|     91   println(s"Function called with ${a} and ${b}.") |         | 
|     92   if (b == 0) a else gcd_db(b, a % b) |         | 
|     93 } |         | 
|     94  |         | 
|     95 gcd_db(48, 18) |         | 
|     96  |         | 
|     97  |         | 
|     98 // Asserts/Testing |         | 
|     99 //================= |         | 
|    100  |         | 
|    101 assert(gcd(48, 18) == 6) |         | 
|    102  |         | 
|    103 assert(gcd(48, 18) == 5, "The gcd test failed") |         | 
|    104  |         | 
|    105  |         | 
|    106  |         | 
|    107 // Higher-Order Functions |         | 
|    108 //======================== |         | 
|    109  |         | 
|    110 // functions can take functions as arguments |         | 
|    111  |         | 
|    112 def even(x: Int) : Boolean = x % 2 == 0 |         | 
|    113 def odd(x: Int) : Boolean = x % 2 == 1 |         | 
|    114  |         | 
|    115 val lst = (1 to 10).toList |         | 
|    116  |         | 
|    117 lst.filter(x => even(x)) |         | 
|    118 lst.filter(even(_)) |         | 
|    119 lst.filter(even) |         | 
|    120  |         | 
|    121 lst.count(even) |         | 
|    122  |         | 
|    123  |         | 
|    124 lst.find(even) |         | 
|    125  |         | 
|    126 val ps = List((3, 0), (3, 2), (4, 2), (2, 2), (2, 0), (1, 1), (1, 0)) |         | 
|    127  |         | 
|    128 lst.sortWith(_ > _) |         | 
|    129 lst.sortWith(_ < _) |         | 
|    130  |         | 
|    131 def lex(x: (Int, Int), y: (Int, Int)) : Boolean =  |         | 
|    132   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1 |         | 
|    133  |         | 
|    134 ps.sortWith(lex) |         | 
|    135  |         | 
|    136 ps.sortBy(_._1) |         | 
|    137 ps.sortBy(_._2) |         | 
|    138  |         | 
|    139 ps.maxBy(_._1) |         | 
|    140 ps.maxBy(_._2) |         | 
|    141  |         | 
|    142  |         | 
|    143  |         | 
|    144 // maps (lower-case) |         | 
|    145 //=================== |         | 
|    146  |         | 
|    147 def double(x: Int): Int = x + x |         | 
|    148 def square(x: Int): Int = x * x |         | 
|    149  |         | 
|    150  |         | 
|    151  |         | 
|    152 val lst = (1 to 10).toList |         | 
|    153  |         | 
|    154 lst.map(x => (double(x), square(x))) |         | 
|    155  |         | 
|    156 lst.map(square) |         | 
|    157  |         | 
|    158 // this is actually how for-comprehensions  |         | 
|    159 // defined as in Scala |         | 
|    160  |         | 
|    161 lst.map(n => square(n)) |         | 
|    162 for (n <- lst) yield square(n) |         | 
|    163  |         | 
|    164 // this can be iterated |         | 
|    165  |         | 
|    166 lst.map(square).filter(_ > 4) |         | 
|    167  |         | 
|    168 lst.map(square).filter(_ > 4).map(square) |         | 
|    169  |         | 
|    170  |         | 
|    171 // lets define our own functions |         | 
|    172 // type of functions, for example f: Int => Int |         | 
|    173  |         | 
|    174 lst.tail |         | 
|    175  |         | 
|    176 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = { |         | 
|    177   if (lst == Nil) Nil |         | 
|    178   else f(lst.head) :: my_map_int(lst.tail, f) |         | 
|    179 } |         | 
|    180  |         | 
|    181 my_map_int(lst, square) |         | 
|    182  |         | 
|    183  |         | 
|    184 // same function using pattern matching: a kind |         | 
|    185 // of switch statement on steroids (see more later on) |         | 
|    186  |         | 
|    187 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = lst match { |         | 
|    188   case Nil => Nil |         | 
|    189   case x::xs => f(x)::my_map_int(xs, f) |         | 
|    190 } |         | 
|    191  |         | 
|    192  |         | 
|    193 // other function types |         | 
|    194 // |         | 
|    195 // f1: (Int, Int) => Int |         | 
|    196 // f2: List[String] => Option[Int] |         | 
|    197 // ...  |         | 
|    198 val lst = (1 to 10).toList |         | 
|    199  |         | 
|    200 def sumOf(f: Int => Int, lst: List[Int]): Int = lst match { |         | 
|    201   case Nil => 0 |         | 
|    202   case x::xs => f(x) + sumOf(f, xs) |         | 
|    203 } |         | 
|    204  |         | 
|    205 def sum_squares(lst: List[Int]) = sumOf(square, lst) |         | 
|    206 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst) |         | 
|    207  |         | 
|    208 sum_squares(lst) |         | 
|    209 sum_cubes(lst) |         | 
|    210  |         | 
|    211 // lets try it factorial |         | 
|    212 def fact(n: Int) : Int =  |         | 
|    213   if (n == 0) 1 else n * fact(n - 1) |         | 
|    214  |         | 
|    215 def sum_fact(lst: List[Int]) = sumOf(fact, lst) |         | 
|    216 sum_fact(lst) |         | 
|    217  |         | 
|    218  |         | 
|    219  |         | 
|    220  |         | 
|    221  |         | 
|    222 // Map type (upper-case) |         | 
|    223 //======================= |         | 
|    224  |         | 
|    225 // Note the difference between map and Map |         | 
|    226  |         | 
|    227 def factors(n: Int) : List[Int] = |         | 
|    228   ((1 until n).filter { divisor => |         | 
|    229       n % divisor == 0 |         | 
|    230     }).toList |         | 
|    231  |         | 
|    232  |         | 
|    233 var ls = (1 to 10).toList |         | 
|    234  |         | 
|    235 val facs = ls.map(n => (n, factors(n))) |         | 
|    236  |         | 
|    237 facs.find(_._1 == 4) |         | 
|    238  |         | 
|    239 // works for lists of pairs |         | 
|    240 facs.toMap |         | 
|    241  |         | 
|    242  |         | 
|    243 facs.toMap.get(4) |         | 
|    244 facs.toMap.getOrElse(42, Nil) |         | 
|    245  |         | 
|    246 val facsMap = facs.toMap |         | 
|    247  |         | 
|    248 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5)) |         | 
|    249 facsMap0.get(1) |         | 
|    250  |         | 
|    251 val facsMap4 = facsMap + (1 -> List(1,2,3,4,5)) |         | 
|    252 facsMap.get(1) |         | 
|    253 facsMap4.get(1) |         | 
|    254  |         | 
|    255 val ls = List("one", "two", "three", "four", "five") |         | 
|    256 ls.groupBy(_.length) |         | 
|    257  |         | 
|    258 ls.groupBy(_.length).get(2) |         | 
|    259  |         | 
|    260  |         | 
|    261  |         | 
|    262 // Option type (again) |         | 
|    263 //===================== |         | 
|    264  |         | 
|    265 // remember, in Java if something unusually happens,  |         | 
|    266 // you return null; |         | 
|    267 // |         | 
|    268 // in Scala you use Option |         | 
|    269 //   - if the value is present, you use Some(value) |         | 
|    270 //   - if no value is present, you use None |         | 
|    271  |         | 
|    272  |         | 
|    273 List(7,2,3,4,5,6).find(_ < 4) |         | 
|    274 List(5,6,7,8,9).find(_ < 4) |         | 
|    275  |         | 
|    276 // operations on options |     96 // operations on options | 
|    277  |     97  | 
|    278 val lst = List(None, Some(1), Some(2), None, Some(3)) |     98 val lst = List(None, Some(1), Some(2), None, Some(3)) | 
|    279  |     99  | 
|    280 lst.flatten |    100 lst.flatten | 
|    299 val lst = List(None, Some(1), Some(2), None, Some(3)) |    119 val lst = List(None, Some(1), Some(2), None, Some(3)) | 
|    300  |    120  | 
|    301 for (x <- lst) yield x.getOrElse(0) |    121 for (x <- lst) yield x.getOrElse(0) | 
|    302  |    122  | 
|    303  |    123  | 
|    304  |         | 
|    305  |         | 
|    306 // error handling with Option (no exceptions) |         | 
|    307 // |         | 
|    308 //  Try(something).getOrElse(what_to_do_in_an_exception) |         | 
|    309 // |         | 
|    310 import scala.util._ |         | 
|    311 import io.Source |         | 
|    312  |         | 
|    313  |         | 
|    314 Source.fromURL("""http://www.inf.ucl.ac.uk/staff/urbanc/""").mkString |         | 
|    315  |         | 
|    316 Try(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString).getOrElse("") |         | 
|    317  |         | 
|    318 Try(Some(Source.fromURL("""http://www.inf.kcl.ac.uk/staff/urbanc/""").mkString)).getOrElse(None) |         | 
|    319  |         | 
|    320  |         | 
|    321 // a function that turns strings into numbers (similar to .toInt) |         | 
|    322 Integer.parseInt("12u34") |         | 
|    323  |         | 
|    324  |         | 
|    325 def get_me_an_int(s: String) : Option[Int] =  |         | 
|    326  Try(Some(Integer.parseInt(s))).getOrElse(None) |         | 
|    327  |         | 
|    328 val lst = List("12345", "foo", "5432", "bar", "x21", "456") |         | 
|    329 for (x <- lst) yield get_me_an_int(x) |         | 
|    330  |         | 
|    331 // summing up all the numbers |         | 
|    332  |         | 
|    333 lst.map(get_me_an_int).flatten.sum |         | 
|    334 lst.map(get_me_an_int).flatten.sum |         | 
|    335  |         | 
|    336  |         | 
|    337 lst.flatMap(get_me_an_int).map(_.toString) |         | 
|    338  |    124  | 
|    339  |    125  | 
|    340 // This may not look any better than working with null in Java, but to |    126 // This may not look any better than working with null in Java, but to | 
|    341 // see the value, you have to put yourself in the shoes of the |    127 // see the value, you have to put yourself in the shoes of the | 
|    342 // consumer of the get_me_an_int function, and imagine you didn't |    128 // consumer of the get_me_an_int function, and imagine you didn't | 
|    352 // even Scala is not immune to problems like this: |    138 // even Scala is not immune to problems like this: | 
|    353  |    139  | 
|    354 List(5,6,7,8,9).indexOf(7) |    140 List(5,6,7,8,9).indexOf(7) | 
|    355 List(5,6,7,8,9).indexOf(10) |    141 List(5,6,7,8,9).indexOf(10) | 
|    356 List(5,6,7,8,9)(-1) |    142 List(5,6,7,8,9)(-1) | 
|         |    143  | 
|         |    144  | 
|         |    145  | 
|         |    146  | 
|         |    147 // Higher-Order Functions | 
|         |    148 //======================== | 
|         |    149  | 
|         |    150 // functions can take functions as arguments | 
|         |    151  | 
|         |    152 def even(x: Int) : Boolean = x % 2 == 0 | 
|         |    153 def odd(x: Int) : Boolean = x % 2 == 1 | 
|         |    154  | 
|         |    155 val lst = (1 to 10).toList | 
|         |    156  | 
|         |    157 lst.filter(x => even(x)) | 
|         |    158 lst.filter(even(_)) | 
|         |    159 lst.filter(even) | 
|         |    160  | 
|         |    161 lst.count(even) | 
|         |    162  | 
|         |    163  | 
|         |    164 lst.find(even) | 
|         |    165  | 
|         |    166 val ps = List((3, 0), (3, 2), (4, 2), (2, 2), (2, 0), (1, 1), (1, 0)) | 
|         |    167  | 
|         |    168 lst.sortWith(_ > _) | 
|         |    169 lst.sortWith(_ < _) | 
|         |    170  | 
|         |    171 def lex(x: (Int, Int), y: (Int, Int)) : Boolean =  | 
|         |    172   if (x._1 == y._1) x._2 < y._2 else x._1 < y._1 | 
|         |    173  | 
|         |    174 ps.sortWith(lex) | 
|         |    175  | 
|         |    176 ps.sortBy(_._1) | 
|         |    177 ps.sortBy(_._2) | 
|         |    178  | 
|         |    179 ps.maxBy(_._1) | 
|         |    180 ps.maxBy(_._2) | 
|         |    181  | 
|         |    182  | 
|         |    183  | 
|         |    184 // maps (lower-case) | 
|         |    185 //=================== | 
|         |    186  | 
|         |    187 def double(x: Int): Int = x + x | 
|         |    188 def square(x: Int): Int = x * x | 
|         |    189  | 
|         |    190  | 
|         |    191 val lst = (1 to 10).toList | 
|         |    192  | 
|         |    193 lst.map(x => (double(x), square(x))) | 
|         |    194  | 
|         |    195 lst.map(square) | 
|         |    196  | 
|         |    197 // this is actually how for-comprehensions  | 
|         |    198 // defined as in Scala | 
|         |    199  | 
|         |    200 lst.map(n => square(n)) | 
|         |    201 for (n <- lst) yield square(n) | 
|         |    202  | 
|         |    203 // this can be iterated | 
|         |    204  | 
|         |    205 lst.map(square).filter(_ > 4) | 
|         |    206  | 
|         |    207 lst.map(square).filter(_ > 4).map(square) | 
|         |    208  | 
|         |    209  | 
|         |    210 // lets define our own functions | 
|         |    211 // type of functions, for example f: Int => Int | 
|         |    212  | 
|         |    213 lst.tail | 
|         |    214  | 
|         |    215 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = { | 
|         |    216   if (lst == Nil) Nil | 
|         |    217   else f(lst.head) :: my_map_int(lst.tail, f) | 
|         |    218 } | 
|         |    219  | 
|         |    220 my_map_int(lst, square) | 
|         |    221  | 
|         |    222  | 
|         |    223 // same function using pattern matching: a kind | 
|         |    224 // of switch statement on steroids (see more later on) | 
|         |    225  | 
|         |    226 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = lst match { | 
|         |    227   case Nil => Nil | 
|         |    228   case x::xs => f(x)::my_map_int(xs, f) | 
|         |    229 } | 
|         |    230  | 
|         |    231  | 
|         |    232 // other function types | 
|         |    233 // | 
|         |    234 // f1: (Int, Int) => Int | 
|         |    235 // f2: List[String] => Option[Int] | 
|         |    236 // ...  | 
|         |    237 val lst = (1 to 10).toList | 
|         |    238  | 
|         |    239 def sumOf(f: Int => Int, lst: List[Int]): Int = lst match { | 
|         |    240   case Nil => 0 | 
|         |    241   case x::xs => f(x) + sumOf(f, xs) | 
|         |    242 } | 
|         |    243  | 
|         |    244 def sum_squares(lst: List[Int]) = sumOf(square, lst) | 
|         |    245 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst) | 
|         |    246  | 
|         |    247 sum_squares(lst) | 
|         |    248 sum_cubes(lst) | 
|         |    249  | 
|         |    250 // lets try it factorial | 
|         |    251 def fact(n: Int) : Int =  | 
|         |    252   if (n == 0) 1 else n * fact(n - 1) | 
|         |    253  | 
|         |    254 def sum_fact(lst: List[Int]) = sumOf(fact, lst) | 
|         |    255 sum_fact(lst) | 
|         |    256  | 
|         |    257  | 
|         |    258  | 
|         |    259 // if you like verbosity, you can full-specify the literal.  | 
|         |    260 // Don't go telling that to people, though | 
|         |    261 (1 to 100).filter((x: Int) => x % 2 == 0).sum  | 
|         |    262  | 
|         |    263 // As x is known to be an Int anyway, you can omit that part | 
|         |    264 (1 to 100).filter(x => x % 2 == 0).sum | 
|         |    265  | 
|         |    266 // As each parameter (only x in this case) is passed only once | 
|         |    267 // you can use the wizardy placeholder syntax | 
|         |    268 (1 to 100).filter(_ % 2 == 0).sum | 
|         |    269  | 
|         |    270 // But if you want to re-use your literal, you can also put it in a value | 
|         |    271 // In this case, explicit types are required because there's nothing to infer from | 
|         |    272 val isEven = (x: Int) => x % 2 == 0 | 
|         |    273 (1 to 100).filter(isEven).sum | 
|         |    274  | 
|         |    275  | 
|         |    276  | 
|         |    277 // Option Type again | 
|         |    278 //=================== | 
|         |    279  | 
|         |    280 // a function that turns strings into numbers (similar to .toInt) | 
|         |    281 Integer.parseInt("12u34") | 
|         |    282  | 
|         |    283  | 
|         |    284 def get_me_an_int(s: String) : Option[Int] =  | 
|         |    285  Try(Some(Integer.parseInt(s))).getOrElse(None) | 
|         |    286  | 
|         |    287 val lst = List("12345", "foo", "5432", "bar", "x21", "456") | 
|         |    288 for (x <- lst) yield get_me_an_int(x) | 
|         |    289  | 
|         |    290 // summing up all the numbers | 
|         |    291  | 
|         |    292 lst.map(get_me_an_int).flatten.sum | 
|         |    293 lst.map(get_me_an_int).flatten.sum | 
|         |    294  | 
|         |    295 lst.flatMap(get_me_an_int).sum | 
|         |    296  | 
|         |    297  | 
|         |    298  | 
|         |    299  | 
|         |    300 // Map type (upper-case) | 
|         |    301 //======================= | 
|         |    302  | 
|         |    303 // Note the difference between map and Map | 
|         |    304  | 
|         |    305 def factors(n: Int) : List[Int] = | 
|         |    306   ((1 until n).filter { divisor => | 
|         |    307       n % divisor == 0 | 
|         |    308     }).toList | 
|         |    309  | 
|         |    310  | 
|         |    311 var ls = (1 to 10).toList | 
|         |    312  | 
|         |    313 val facs = ls.map(n => (n, factors(n))) | 
|         |    314  | 
|         |    315 facs.find(_._1 == 4) | 
|         |    316  | 
|         |    317 // works for lists of pairs | 
|         |    318 facs.toMap | 
|         |    319  | 
|         |    320  | 
|         |    321 facs.toMap.get(4) | 
|         |    322 facs.toMap.getOrElse(42, Nil) | 
|         |    323  | 
|         |    324 val facsMap = facs.toMap | 
|         |    325  | 
|         |    326 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5)) | 
|         |    327 facsMap0.get(1) | 
|         |    328  | 
|         |    329 val facsMap4 = facsMap + (1 -> List(1,2,3,4,5)) | 
|         |    330 facsMap.get(1) | 
|         |    331 facsMap4.get(1) | 
|         |    332  | 
|         |    333 val ls = List("one", "two", "three", "four", "five") | 
|         |    334 ls.groupBy(_.length) | 
|         |    335  | 
|         |    336 ls.groupBy(_.length).get(2) | 
|         |    337  | 
|    357  |    338  | 
|    358  |    339  | 
|    359  |    340  | 
|    360 // Pattern Matching |    341 // Pattern Matching | 
|    361 //================== |    342 //================== |