updated
authorChristian Urban <urbanc@in.tum.de>
Thu, 24 Nov 2016 11:43:07 +0000
changeset 71 19dff7218b0d
parent 70 6024381415cb
child 72 9d8b172f5337
updated
progs/lecture3.scala
--- a/progs/lecture3.scala	Thu Nov 24 11:25:38 2016 +0000
+++ b/progs/lecture3.scala	Thu Nov 24 11:43:07 2016 +0000
@@ -23,7 +23,7 @@
 // Tail recursion
 //================
 
-def my_contains(elem: Int, lst: List[Int]) : Boolean = lst match {
+def my_contains(elem: Int, lst: List[Int]): Boolean = lst match {
   case Nil => false
   case x::xs => 
     if (x == elem) true else my_contains(elem, xs)
@@ -36,12 +36,12 @@
 my_contains(1000001, (1 to 1000000).toList)
 
 
-//factorial 0.1
+//factorial V0.1
 
 def fact(n: Long): Long = 
   if (n == 0) 1 else n * fact(n - 1)
 
-fact(10000)
+fact(10000)                        // produces a stackoverflow
 
 
 def factT(n: BigInt, acc: BigInt): BigInt =
@@ -50,24 +50,24 @@
 
 factT(10000, 1)
 
-// my_contains and factT are tail recursive 
+// the functions my_contains and factT are tail-recursive 
 // you can check this with 
 
 import scala.annotation.tailrec
 
 // and the annotation @tailrec
 
-// for tail-recursive functions the compiler
-// generates a loop-like code, which does not
+// for tail-recursive functions the scala compiler
+// generates loop-like code, which does not need
 // to allocate stack-space in each recursive
 // call; scala can do this only for tail-recursive
 // functions
 
 // consider the following "stupid" version of the
-// coin exchange problem: given some coins and a,
-// total, what is the change can you get
+// coin exchange problem: given some coins and a
+// total, what is the change can you get?
 
-val coins = List(4,5,6,8,10,13,19,20,21,24,38,39, 40)
+val coins = List(4,5,6,8,10,13,19,20,21,24,38,39,40)
 
 def first_positive[B](lst: List[Int], f: Int => Option[B]): Option[B] = lst match {
   case Nil => None
@@ -98,26 +98,30 @@
 import scala.annotation.tailrec
 
 @tailrec
-def asearch(total: Int, coins: List[Int], acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match {
+def searchT(total: Int, coins: List[Int], acc_cs: List[List[Int]]): Option[List[Int]] = acc_cs match {
   case Nil => None
   case x::xs => 
-    if (total < x.sum) asearch(total, coins, xs)
+    if (total < x.sum) searchT(total, coins, xs)
     else if (x.sum == total) Some(x) 
-    else asearch(total, coins, coins.filter(_ > 0).map(_::x) ::: xs)
+    else searchT(total, coins, coins.filter(_ > 0).map(_::x) ::: xs)
 }
 
 val start_acc = coins.filter(_ > 0).map(List(_))
-asearch(11, junk_coins, start_acc)
-asearch(111, junk_coins, start_acc)
-asearch(111111, junk_coins, start_acc)
+searchT(11, junk_coins, start_acc)
+searchT(111, junk_coins, start_acc)
+searchT(111111, junk_coins, start_acc)
 
 // moral: whenever a recursive function is resource-critical
 // (i.e. works on large recursion depth), then you need to
 // write it in tail-recursive fashion
 
 
-// Polymorphism
-//==============
+// Polymorphic Types
+//===================
+
+// You do not want to frite functions like contains, first 
+// and so on for every type of lists.
+
 
 def length_int_list(lst: List[Int]): Int = lst match {
   case Nil => 0
@@ -185,17 +189,17 @@
 
 
 
-// Regular expressions - the power of DSLs
-//=========================================
+// Regular expressions - the power of DSLs in Scala
+//==================================================
 
 
 abstract class Rexp
 case object ZERO extends Rexp
 case object ONE extends Rexp
 case class CHAR(c: Char) extends Rexp
-case class ALT(r1: Rexp, r2: Rexp) extends Rexp 
-case class SEQ(r1: Rexp, r2: Rexp) extends Rexp 
-case class STAR(r: Rexp) extends Rexp 
+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)*