126   | 
   126   | 
   127 for (x <- lst) yield x.getOrElse(0)  | 
   127 for (x <- lst) yield x.getOrElse(0)  | 
   128   | 
   128   | 
   129   | 
   129   | 
   130 // a function that turns strings into numbers (similar to .toInt)  | 
   130 // a function that turns strings into numbers (similar to .toInt)  | 
   131 Integer.parseInt("1234") | 
   131 Integer.parseInt("12u34") | 
   132   | 
   132   | 
   133   | 
   133   | 
   134 def get_me_an_int(s: String) : Option[Int] =   | 
   134 def get_me_an_int(s: String) : Option[Int] =   | 
   135  Try(Some(Integer.parseInt(s))).getOrElse(None)  | 
   135  Try(Some(Integer.parseInt(s))).getOrElse(None)  | 
   136   | 
   136   | 
   151 List(5,6,7,8,9).indexOf(7)  | 
   151 List(5,6,7,8,9).indexOf(7)  | 
   152 List(5,6,7,8,9).indexOf(10)  | 
   152 List(5,6,7,8,9).indexOf(10)  | 
   153 List(5,6,7,8,9)(-1)  | 
   153 List(5,6,7,8,9)(-1)  | 
   154   | 
   154   | 
   155   | 
   155   | 
   156   | 
   156 Try({ | 
         | 
   157   val x = 3  | 
         | 
   158   val y = 0  | 
         | 
   159   Some(x / y)  | 
         | 
   160 }).getOrElse(None)  | 
   157   | 
   161   | 
   158 // Higher-Order Functions  | 
   162 // Higher-Order Functions  | 
   159 //========================  | 
   163 //========================  | 
   160   | 
   164   | 
   161 // functions can take functions as arguments  | 
   165 // functions can take functions as arguments  | 
   163   | 
   167   | 
   164 def even(x: Int) : Boolean = x % 2 == 0  | 
   168 def even(x: Int) : Boolean = x % 2 == 0  | 
   165 def odd(x: Int) : Boolean = x % 2 == 1  | 
   169 def odd(x: Int) : Boolean = x % 2 == 1  | 
   166   | 
   170   | 
   167 val lst = (1 to 10).toList  | 
   171 val lst = (1 to 10).toList  | 
         | 
   172 lst.reverse.sorted  | 
         | 
   173   | 
   168   | 
   174   | 
   169 lst.filter(even)  | 
   175 lst.filter(even)  | 
   170 lst.count(even)  | 
   176 lst.count(odd)  | 
   171 lst.find(even)  | 
   177 lst.find(even)  | 
   172   | 
   178 lst.exists(even)  | 
   173 lst.filter(x => x % 2 == 0)  | 
   179   | 
         | 
   180 lst.filter(_ < 4)   | 
         | 
   181 lst.filter(x => x % 2 == 1)  | 
   174 lst.filter(_ % 2 == 0)  | 
   182 lst.filter(_ % 2 == 0)  | 
   175   | 
   183   | 
   176 lst.sortWith(_ > _)  | 
   184   | 
         | 
   185 lst.sortWith((x, y) => x > y)  | 
   177 lst.sortWith(_ < _)  | 
   186 lst.sortWith(_ < _)  | 
   178   | 
   187   | 
   179 // but this only works when the arguments are clear, but   | 
   188 // but this only works when the arguments are clear, but   | 
   180 // not with multiple occurences  | 
   189 // not with multiple occurences  | 
   181 lst.find(n => odd(n) && n > 2)  | 
   190 lst.find(n => odd(n) && n > 2)  | 
   216   | 
   225   | 
   217 // this can be iterated  | 
   226 // this can be iterated  | 
   218   | 
   227   | 
   219 lst.map(square).filter(_ > 4)  | 
   228 lst.map(square).filter(_ > 4)  | 
   220   | 
   229   | 
   221 lst.map(square).filter(_ > 4).map(square)  | 
   230 (lst.map(square)  | 
         | 
   231    .filter(_ > 4)  | 
         | 
   232    .map(square))  | 
   222   | 
   233   | 
   223   | 
   234   | 
   224 // lets define our own higher-order functions  | 
   235 // lets define our own higher-order functions  | 
   225 // type of functions is for example Int => Int  | 
   236 // type of functions is for example Int => Int  | 
         | 
   237   | 
         | 
   238   | 
         | 
   239 0 :: List(3,4,5,6)  | 
   226   | 
   240   | 
   227   | 
   241   | 
   228 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = { | 
   242 def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = { | 
   229   if (lst == Nil) Nil  | 
   243   if (lst == Nil) Nil  | 
   230   else f(lst.head) :: my_map_int(lst.tail, f)  | 
   244   else f(lst.head) :: my_map_int(lst.tail, f)  | 
   248 // f1: (Int, Int) => Int  | 
   262 // f1: (Int, Int) => Int  | 
   249 // f2: List[String] => Option[Int]  | 
   263 // f2: List[String] => Option[Int]  | 
   250 // ...   | 
   264 // ...   | 
   251 val lst = (1 to 10).toList  | 
   265 val lst = (1 to 10).toList  | 
   252   | 
   266   | 
   253 def sumOf(f: Int => Int, lst: List[Int]): Int = lst match { | 
   267 lst.sum  | 
         | 
   268   | 
         | 
   269 val lst = List(1,2,3,4)  | 
         | 
   270   | 
         | 
   271 lst.head  | 
         | 
   272 lst.tail  | 
         | 
   273   | 
         | 
   274 def sumOf(f: Int => Int, lst: List[Int]): Int =   | 
         | 
   275 lst match { | 
   254   case Nil => 0  | 
   276   case Nil => 0  | 
   255   case x::xs => f(x) + sumOf(f, xs)  | 
   277   case x::foo => f(x) + sumOf(f, foo)  | 
   256 }  | 
   278 }  | 
   257   | 
   279   | 
   258 def sum_squares(lst: List[Int]) = sumOf(square, lst)  | 
   280 def sum_squares(lst: List[Int]) = sumOf(square, lst)  | 
   259 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst)  | 
   281 def sum_cubes(lst: List[Int])   = sumOf(x => x * x * x, lst)  | 
   260   | 
   282   | 
   303   | 
   325   | 
   304 lst.flatMap(get_me_an_int).sum  | 
   326 lst.flatMap(get_me_an_int).sum  | 
   305   | 
   327   | 
   306 // maps on Options  | 
   328 // maps on Options  | 
   307   | 
   329   | 
   308 get_me_an_int("1234").map(even) | 
   330 get_me_an_int("12345").map(even) | 
   309 get_me_an_int("12u34").map(even) | 
   331 get_me_an_int("12u34").map(even) | 
         | 
   332   | 
         | 
   333 def my_map_option(o: Option[Int], f : Int => Int) : Option[Int] = { | 
         | 
   334 o match { | 
         | 
   335    case None => None  | 
         | 
   336    case Some(foo) => Some(f(foo))  | 
         | 
   337 }}  | 
         | 
   338   | 
         | 
   339 my_map_option(Some(4), square)  | 
         | 
   340 my_map_option(None, square)  | 
   310   | 
   341   | 
   311   | 
   342   | 
   312   | 
   343   | 
   313 // Map type (upper-case)  | 
   344 // Map type (upper-case)  | 
   314 //=======================  | 
   345 //=======================  | 
   315   | 
   346   | 
   316 // Note the difference between map and Map  | 
   347 // Note the difference between map and Map  | 
   317   | 
   348   | 
         | 
   349 val ascii = ('a' to 'z').map(c => (c, c.toInt)).toList | 
         | 
   350   | 
         | 
   351 val ascii_Map = ascii.toMap  | 
         | 
   352   | 
         | 
   353   | 
   318 def factors(n: Int) : List[Int] =  | 
   354 def factors(n: Int) : List[Int] =  | 
   319   (2 until n).toList.filter(n % _ == 0)  | 
   355   (2 until n).toList.filter(n % _ == 0)  | 
   320   | 
   356   | 
   321 var ls = (1 to 10).toList  | 
   357 var ls = (1 to 10).toList  | 
   322 val facs = ls.map(n => (n, factors(n)))  | 
   358 val facs = ls.map(n => (n, factors(n)))  | 
   325   | 
   361   | 
   326 // works for lists of pairs  | 
   362 // works for lists of pairs  | 
   327 facs.toMap  | 
   363 facs.toMap  | 
   328   | 
   364   | 
   329   | 
   365   | 
   330 facs.toMap.get(4)  | 
   366 facs.toMap.get(40)  | 
   331 facs.toMap.getOrElse(42, Nil)  | 
   367 facs.toMap.getOrElse(42, Nil)  | 
   332   | 
   368   | 
   333 val facsMap = facs.toMap  | 
   369 val facsMap = facs.toMap  | 
   334   | 
   370   | 
   335 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5))  | 
   371 val facsMap0 = facsMap + (0 -> List(1,2,3,4,5))  | 
   367   | 
   403   | 
   368   | 
   404   | 
   369 // recall  | 
   405 // recall  | 
   370 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten  | 
   406 val lst = List(None, Some(1), Some(2), None, Some(3)).flatten  | 
   371   | 
   407   | 
   372 def my_flatten(xs: List[Option[Int]]): List[Int] = xs match { | 
   408 def my_flatten(xs: List[Option[Int]]): List[Int] =   | 
         | 
   409 xs match { | 
   373   case Nil => Nil   | 
   410   case Nil => Nil   | 
   374   case None::rest => my_flatten(rest)  | 
   411   case None::rest => my_flatten(rest)  | 
   375   case Some(v)::rest => v :: my_flatten(rest)  | 
   412   case Some(v)::rest => v :: my_flatten(rest)  | 
   376 }  | 
   413 }  | 
   377   | 
   414   | 
   379   | 
   416   | 
   380   | 
   417   | 
   381 // another example with a default case  | 
   418 // another example with a default case  | 
   382 def get_me_a_string(n: Int): String = n match { | 
   419 def get_me_a_string(n: Int): String = n match { | 
   383   case 0 | 1 | 2 => "small"  | 
   420   case 0 | 1 | 2 => "small"  | 
   384   case _ => "big"  | 
   421 }  | 
   385 }  | 
   422   | 
   386   | 
   423 get_me_a_string(3)  | 
   387 get_me_a_string(0)  | 
         | 
   388   | 
   424   | 
   389   | 
   425   | 
   390 // you can also have cases combined  | 
   426 // you can also have cases combined  | 
   391 def season(month: String) : String = month match { | 
   427 def season(month: String) : String = month match { | 
   392   case "March" | "April" | "May" => "It's spring"  | 
   428   case "March" | "April" | "May" => "It's spring"  | 
   444    Combinations of length 3:  | 
   480    Combinations of length 3:  | 
   445      | 
   481      | 
   446      aaa, baa, caa, and so on......  | 
   482      aaa, baa, caa, and so on......  | 
   447 */  | 
   483 */  | 
   448   | 
   484   | 
         | 
   485 def combs(cs: List[Char], n: Int) : List[String] = { | 
         | 
   486   if (n == 0) List("") | 
         | 
   487   else for (c <- cs; s <- combs(cs, n - 1)) yield s"$c$s"  | 
         | 
   488 }  | 
         | 
   489   | 
         | 
   490 combs(List('a', 'b', 'c'), 3) | 
         | 
   491   | 
         | 
   492   | 
         | 
   493   | 
   449 def combs(cs: List[Char], l: Int) : List[String] = { | 
   494 def combs(cs: List[Char], l: Int) : List[String] = { | 
   450   if (l == 0) List("") | 
   495   if (l == 0) List("") | 
   451   else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s"  | 
   496   else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s"  | 
   452 }  | 
   497 }  | 
   453   | 
   498   | 
   454 combs("abc".toList, 2) | 
   499 combs("abc".toList, 2) | 
   455   | 
   500   | 
   456   | 
         | 
   457 // another well-known example  | 
         | 
   458   | 
         | 
   459 def move(from: Char, to: Char) =  | 
         | 
   460   println(s"Move disc from $from to $to!")  | 
         | 
   461   | 
         | 
   462 def hanoi(n: Int, from: Char, via: Char, to: Char) : Unit = { | 
         | 
   463   if (n == 0) ()  | 
         | 
   464   else { | 
         | 
   465     hanoi(n - 1, from, to, via)  | 
         | 
   466     move(from, to)  | 
         | 
   467     hanoi(n - 1, via, from, to)  | 
         | 
   468   }  | 
         | 
   469 }   | 
         | 
   470   | 
         | 
   471 hanoi(4, 'A', 'B', 'C')  | 
         | 
   472   | 
   501   | 
   473   | 
   502   | 
   474 // A Recursive Web Crawler / Email Harvester  | 
   503 // A Recursive Web Crawler / Email Harvester  | 
   475 //===========================================  | 
   504 //===========================================  | 
   476 //  | 
   505 //  |