progs/lecture4.scala
changeset 226 5e489c9fe47b
parent 225 56732dbefcff
child 242 e6b34f617915
--- 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))