progs/lecture4.scala
changeset 507 2e3945ff7b66
parent 491 2a30c7dfe3ed
equal deleted inserted replaced
506:28f78d9081d7 507:2e3945ff7b66
    35 }
    35 }
    36 length(List("1", "2", "3", "4"))
    36 length(List("1", "2", "3", "4"))
    37 length(List(1, 2, 3, 4))
    37 length(List(1, 2, 3, 4))
    38 
    38 
    39 
    39 
    40 length[String](List(1, 2, 3, 4))
    40 length[Int](List(1, 2, 3, 4))
    41 
    41 
    42 
    42 
    43 def map[A, B](lst: List[A], f: A => B): List[B] = lst match {
    43 def map[A, B](lst: List[A], f: A => B): List[B] = lst match {
    44   case Nil => Nil
    44   case Nil => Nil
    45   case x::xs => f(x)::map(xs, f) 
    45   case x::xs => f(x)::map(xs, f) 
   245 
   245 
   246 
   246 
   247 // Tail recursion
   247 // Tail recursion
   248 //================
   248 //================
   249 
   249 
       
   250 @tailrec
   250 def fact(n: BigInt): BigInt = 
   251 def fact(n: BigInt): BigInt = 
   251   if (n == 0) 1 else n * fact(n - 1)
   252   if (n == 0) 1 else n * fact(n - 1)
       
   253 
       
   254 fact(3) -> fact(2)
       
   255 
   252 
   256 
   253 
   257 
   254 fact(10)          
   258 fact(10)          
   255 fact(1000)        
   259 fact(1000)        
   256 fact(100000)       
   260 fact(100000)       
   258 
   262 
   259 def factT(n: BigInt, acc: BigInt): BigInt =
   263 def factT(n: BigInt, acc: BigInt): BigInt =
   260   if (n == 0) acc else factT(n - 1, n * acc)
   264   if (n == 0) acc else factT(n - 1, n * acc)
   261 
   265 
   262 
   266 
   263 factT(1000,1)
   267 factT(10,1)
   264 println(factT(100000, 1))
   268 println(factT(100000, 1))
   265 
   269 
   266 
   270 
   267 // there is a flag for ensuring a function is tail recursive
   271 // there is a flag for ensuring a function is tail recursive
   268 import scala.annotation.tailrec
   272 import scala.annotation.tailrec
   301 def length[A](xs: List[A]) : Int = xs match {
   305 def length[A](xs: List[A]) : Int = xs match {
   302   case Nil => 0
   306   case Nil => 0
   303   case _ :: tail => 1 + length(tail)
   307   case _ :: tail => 1 + length(tail)
   304 }
   308 }
   305 
   309 
   306 length(List.fill(100000)(1))
   310 val long_lst = List.fill(100000)(1)
       
   311 
       
   312 length(long_lst)
       
   313 long_lst.length
   307 
   314 
   308 def lengthT[A](xs: List[A], acc : Int = 0) : Int = xs match {
   315 def lengthT[A](xs: List[A], acc : Int = 0) : Int = xs match {
   309   case Nil => acc
   316   case Nil => acc
   310   case _ :: tail => lengthT(tail, 1 + acc)
   317   case _ :: tail => lengthT(tail, 1 + acc)
   311 }
   318 }
   312 
   319 
   313 lengthT(List.fill(100000)(1))
   320       
   314 
   321 
   315 
   322 
   316 
   323 
   317 
   324 
   318 
   325 
   626 
   633 
   627 
   634 
   628 // Regular expressions - the power of DSLs in Scala
   635 // Regular expressions - the power of DSLs in Scala
   629 //==================================================
   636 //==================================================
   630 
   637 
   631 abstract class Rexp
   638 enum Rexp {
   632 case object ZERO extends Rexp                     // nothing
   639   case ZERO                      // nothing
   633 case object ONE extends Rexp                      // the empty string
   640   case ONE                       // the empty string
   634 case class CHAR(c: Char) extends Rexp             // a character c
   641   case CHAR(c: Char)             // a character c
   635 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2
   642   case ALT(r1: Rexp, r2: Rexp)   // alternative  r1 + r2
   636 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2  
   643   case SEQ(r1: Rexp, r2: Rexp)   // sequence     r1 . r2  
   637 case class STAR(r: Rexp) extends Rexp             // star         r*
   644   case STAR(r: Rexp)             // star         r*
   638 
   645 }
   639 
   646 import Rexp._
   640 
   647 
   641 // writing (ab)* in the format above is 
   648 // writing (ab)* in the format above is 
   642 // tedious
   649 // tedious
   643 val r0 = STAR(SEQ(CHAR('a'), CHAR('b')))
   650 val r0 = STAR(SEQ(CHAR('a'), CHAR('b')))
   644 
   651 
   674               "5" | "6" | "7" | "8" | "9")
   681               "5" | "6" | "7" | "8" | "9")
   675 val sign = "+" | "-" | ""
   682 val sign = "+" | "-" | ""
   676 val number = sign ~ digit ~ digit.% 
   683 val number = sign ~ digit ~ digit.% 
   677 
   684 
   678 
   685 
   679 
   686 extension (n: Int) {
       
   687   def ++ = n + 1
       
   688 }
       
   689 
       
   690 def --(n: Int) = n - 1
       
   691 
       
   692 val n = 3
       
   693 val m = (n.++)  
       
   694 val k = --(n)  
   680 
   695 
   681 // In mandelbrot.scala I used complex (imaginary) numbers 
   696 // In mandelbrot.scala I used complex (imaginary) numbers 
   682 // and implemented the usual arithmetic operations for complex 
   697 // and implemented the usual arithmetic operations for complex 
   683 // numbers.
   698 // numbers.
   684 
   699