--- a/progs/lecture4.scala Fri Nov 30 08:56:22 2018 +0000
+++ b/progs/lecture4.scala Fri Nov 30 13:06:09 2018 +0000
@@ -8,21 +8,6 @@
// You do not want to write functions like contains, first,
// length and so on for every type of lists.
-List("one", "two", "three", "four")
-
-
-
-
-
-
-
-
-
-
-
-
-
-
def length_string_list(lst: List[String]): Int = lst match {
case Nil => 0
@@ -51,7 +36,7 @@
case x::xs => f(x)::map(xs, f)
}
-map(List(1, 2, 3, 4), (x: Int) => x * x)
+map(List(1, 2, 3, 4), (x: Int) => x.toString)
// Remember?
@@ -63,6 +48,8 @@
val ls = List(1,2,3,3,2,4,3,2,1)
ls.distinct
+ls.minBy(_._2)
+ls.sortBy(_._1)
def distinctBy[B, C](xs: List[B],
f: B => C,
@@ -92,7 +79,7 @@
val x = id(322) // Int
val y = id("hey") // String
-val z = id(Set(1,2,3,4)) // Set[Int]
+val z = id(Set[Int](1,2,3,4)) // Set[Int]
@@ -111,7 +98,8 @@
// arr[0] = "Hello World";
-// Scala gives you a compile-time error
+// Scala gives you a compile-time error, which
+// is much better.
var arr = Array[Int]()
arr(0) = "Hello World"
@@ -119,18 +107,20 @@
-
-
//
// Object Oriented Programming in Scala
//
// =====================================
abstract class Animal
-case class Bird(name: String) extends Animal
+case class Bird(name: String) extends Animal {
+ override def toString = name
+}
case class Mammal(name: String) extends Animal
case class Reptile(name: String) extends Animal
+Bird("Sparrow")
+
println(Bird("Sparrow"))
println(Bird("Sparrow").toString)
@@ -142,7 +132,7 @@
// There is a very convenient short-hand notation
-// for constructors
+// for constructors:
class Fraction(x: Int, y: Int) {
def numer = x
@@ -186,7 +176,7 @@
// ...to allow the notation n + m * i
import scala.language.implicitConversions
-object i extends Complex(0, 1)
+val i = Complex(0, 1)
implicit def double2complex(re: Double) = Complex(re, 0)
@@ -222,6 +212,7 @@
// DFAs in Scala
+//===============
import scala.util.Try
@@ -348,7 +339,8 @@
// Q: Why the kerfuffle about the polymorphic types in DFAs/NFAs?
-// A: Subset construction.
+// A: Subset construction. Here the state type for the DFA is
+// sets of states.
def subset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = {
DFA(nfa.starts,
@@ -393,21 +385,21 @@
-
// Regular expressions - the power of DSLs in Scala
//==================================================
abstract class Rexp
-case object ZERO extends Rexp // nothing
-case object ONE extends Rexp // the empty string
-case class CHAR(c: Char) extends Rexp // a character c
-case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2
-case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 . r2
-case class STAR(r: Rexp) extends Rexp // star r*
+case object ZERO extends Rexp // nothing
+case object ONE extends Rexp // the empty string
+case class CHAR(c: Char) extends Rexp // a character c
+case class ALT(r1: Rexp, r2: Rexp) extends Rexp // alternative r1 + r2
+case class SEQ(r1: Rexp, r2: Rexp) extends Rexp // sequence r1 . r2
+case class STAR(r: Rexp) extends Rexp // star r*
-// (ab)*
+// writing (ab)* in the format above is
+// tedious
val r0 = STAR(SEQ(CHAR('a'), CHAR('b')))
@@ -434,6 +426,7 @@
def ~ (s: Rexp) = SEQ(r, s)
}
+
implicit def stringOps (s: String) = new {
def | (r: Rexp) = ALT(s, r)
def | (r: String) = ALT(s, r)
@@ -452,7 +445,9 @@
// Lazy Evaluation
//=================
//
-// do not evaluate arguments just yet
+// Do not evaluate arguments just yet:
+// this uses the => in front of the type
+// of the code-argument
def time_needed[T](i: Int, code: => T) = {
val start = System.nanoTime()
@@ -468,5 +463,6 @@
("a" * 10).matches(evil)
("a" * 10000).matches(evil)
("a" * 20000).matches(evil)
+("a" * 50000).matches(evil)
-time_needed(2, ("a" * 10000).matches(evil))
+time_needed(1, ("a" * 50000).matches(evil))