diff -r b84ea52bfd8f -r cdfb2ce30a3d progs/lecture2.scala --- a/progs/lecture2.scala Tue Nov 12 10:47:27 2019 +0000 +++ b/progs/lecture2.scala Tue Nov 19 00:40:27 2019 +0000 @@ -128,7 +128,7 @@ // a function that turns strings into numbers (similar to .toInt) -Integer.parseInt("1234") +Integer.parseInt("12u34") def get_me_an_int(s: String) : Option[Int] = @@ -153,7 +153,11 @@ List(5,6,7,8,9)(-1) - +Try({ + val x = 3 + val y = 0 + Some(x / y) +}).getOrElse(None) // Higher-Order Functions //======================== @@ -165,15 +169,20 @@ def odd(x: Int) : Boolean = x % 2 == 1 val lst = (1 to 10).toList +lst.reverse.sorted + lst.filter(even) -lst.count(even) +lst.count(odd) lst.find(even) +lst.exists(even) -lst.filter(x => x % 2 == 0) +lst.filter(_ < 4) +lst.filter(x => x % 2 == 1) lst.filter(_ % 2 == 0) -lst.sortWith(_ > _) + +lst.sortWith((x, y) => x > y) lst.sortWith(_ < _) // but this only works when the arguments are clear, but @@ -188,7 +197,7 @@ ps.sortWith(lex) -ps.sortBy(_._1) +ps.sortBy(x => x._1) ps.sortBy(_._2) ps.maxBy(_._1) @@ -218,13 +227,18 @@ lst.map(square).filter(_ > 4) -lst.map(square).filter(_ > 4).map(square) +(lst.map(square) + .filter(_ > 4) + .map(square)) // lets define our own higher-order functions // type of functions is for example Int => Int +0 :: List(3,4,5,6) + + def my_map_int(lst: List[Int], f: Int => Int) : List[Int] = { if (lst == Nil) Nil else f(lst.head) :: my_map_int(lst.tail, f) @@ -250,9 +264,17 @@ // ... val lst = (1 to 10).toList -def sumOf(f: Int => Int, lst: List[Int]): Int = lst match { +lst.sum + +val lst = List(1,2,3,4) + +lst.head +lst.tail + +def sumOf(f: Int => Int, lst: List[Int]): Int = +lst match { case Nil => 0 - case x::xs => f(x) + sumOf(f, xs) + case x::foo => f(x) + sumOf(f, foo) } def sum_squares(lst: List[Int]) = sumOf(square, lst) @@ -305,9 +327,18 @@ // maps on Options -get_me_an_int("1234").map(even) +get_me_an_int("12345").map(even) get_me_an_int("12u34").map(even) +def my_map_option(o: Option[Int], f : Int => Int) : Option[Int] = { +o match { + case None => None + case Some(foo) => Some(f(foo)) +}} + +my_map_option(Some(4), square) +my_map_option(None, square) + // Map type (upper-case) @@ -315,6 +346,11 @@ // Note the difference between map and Map +val ascii = ('a' to 'z').map(c => (c, c.toInt)).toList + +val ascii_Map = ascii.toMap + + def factors(n: Int) : List[Int] = (2 until n).toList.filter(n % _ == 0) @@ -327,7 +363,7 @@ facs.toMap -facs.toMap.get(4) +facs.toMap.get(40) facs.toMap.getOrElse(42, Nil) val facsMap = facs.toMap @@ -344,7 +380,7 @@ val ls = List("one", "two", "three", "four", "five") ls.groupBy(_.length) -ls.groupBy(_.length).get(3) +ls.groupBy(_.length).get(5) @@ -369,7 +405,8 @@ // recall val lst = List(None, Some(1), Some(2), None, Some(3)).flatten -def my_flatten(xs: List[Option[Int]]): List[Int] = xs match { +def my_flatten(xs: List[Option[Int]]): List[Int] = +xs match { case Nil => Nil case None::rest => my_flatten(rest) case Some(v)::rest => v :: my_flatten(rest) @@ -381,10 +418,9 @@ // another example with a default case def get_me_a_string(n: Int): String = n match { case 0 | 1 | 2 => "small" - case _ => "big" } -get_me_a_string(0) +get_me_a_string(3) // you can also have cases combined @@ -446,6 +482,15 @@ aaa, baa, caa, and so on...... */ +def combs(cs: List[Char], n: Int) : List[String] = { + if (n == 0) List("") + else for (c <- cs; s <- combs(cs, n - 1)) yield s"$c$s" +} + +combs(List('a', 'b', 'c'), 3) + + + def combs(cs: List[Char], l: Int) : List[String] = { if (l == 0) List("") else for (c <- cs; s <- combs(cs, l - 1)) yield s"$c$s" @@ -454,22 +499,6 @@ combs("abc".toList, 2) -// another well-known example - -def move(from: Char, to: Char) = - println(s"Move disc from $from to $to!") - -def hanoi(n: Int, from: Char, via: Char, to: Char) : Unit = { - if (n == 0) () - else { - hanoi(n - 1, from, to, via) - move(from, to) - hanoi(n - 1, via, from, to) - } -} - -hanoi(4, 'A', 'B', 'C') - // A Recursive Web Crawler / Email Harvester //===========================================