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