progs/lecture4.scala
changeset 381 116fa3c8584f
parent 380 d19b0a50ceb9
child 382 1bd800376e0c
equal deleted inserted replaced
380:d19b0a50ceb9 381:116fa3c8584f
   521 // late extension problem; namely, given a class C and a class T, 
   521 // late extension problem; namely, given a class C and a class T, 
   522 // how to have C extend T without touching or recompiling C. 
   522 // how to have C extend T without touching or recompiling C. 
   523 // Conversions add a wrapper when a member of T is requested 
   523 // Conversions add a wrapper when a member of T is requested 
   524 // from an instance of C.
   524 // from an instance of C.
   525 
   525 
   526 //Another example (TimeUnit in 2.13?)
   526 
   527 
   527 
   528 import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES}
   528 import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES}
   529 
   529 
   530 case class Duration(time: Long, unit: TimeUnit) {
   530 case class Duration(time: Long, unit: TimeUnit) {
   531   def +(o: Duration) = 
   531   def +(o: Duration) = 
   532     Duration(time + unit.convert(o.time, o.unit), unit)
   532     Duration(time + unit.convert(o.time, o.unit), unit)
   533 }
   533 }
   534 
   534 
   535 implicit class Int2Duration(that: Int) {
   535 implicit class Int2Duration(that: Int) {
   536   def seconds = new Duration(that, SECONDS)
   536   def seconds = Duration(that, SECONDS)
   537   def minutes = new Duration(that, MINUTES)
   537   def minutes = Duration(that, MINUTES)
   538 }
   538 }
   539 
   539 
   540 5.seconds + 2.minutes   //Duration(125L, SECONDS )
   540 5.seconds + 2.minutes   //Duration(125L, SECONDS )
   541 2.minutes + 60.seconds
   541 2.minutes + 60.seconds
   542 
   542 
   572 }
   572 }
   573 
   573 
   574 implicit def string2rexp(s: String): Rexp = 
   574 implicit def string2rexp(s: String): Rexp = 
   575   charlist2rexp(s.toList)
   575   charlist2rexp(s.toList)
   576 
   576 
   577 "(a|b)"
   577 val r1 = STAR("hello")
   578 
   578 val r2 = STAR("hello") | STAR("world")
   579 val r1 = STAR("ab")
   579 
   580 val r2 = (STAR("ab")) | (STAR("ba"))
       
   581 val r3 = STAR(SEQ("ab", ALT("a", "b")))
       
   582 
   580 
   583 implicit def RexpOps (r: Rexp) = new {
   581 implicit def RexpOps (r: Rexp) = new {
   584   def | (s: Rexp) = ALT(r, s)
   582   def | (s: Rexp) = ALT(r, s)
   585   def % = STAR(r)
   583   def % = STAR(r)
   586   def ~ (s: Rexp) = SEQ(r, s)
   584   def ~ (s: Rexp) = SEQ(r, s)
   593   def ~ (r: Rexp) = SEQ(s, r)
   591   def ~ (r: Rexp) = SEQ(s, r)
   594   def ~ (r: String) = SEQ(s, r)
   592   def ~ (r: String) = SEQ(s, r)
   595 }
   593 }
   596 
   594 
   597 //example regular expressions
   595 //example regular expressions
       
   596 
       
   597 
   598 val digit = ("0" | "1" | "2" | "3" | "4" | 
   598 val digit = ("0" | "1" | "2" | "3" | "4" | 
   599               "5" | "6" | "7" | "8" | "9")
   599               "5" | "6" | "7" | "8" | "9")
   600 val sign = "+" | "-" | ""
   600 val sign = "+" | "-" | ""
   601 val number = sign ~ digit ~ digit.% 
   601 val number = sign ~ digit ~ digit.% 
   602 
   602 
   603 
   603 
   604 
   604 
   605 // Mind-Blowing Regular Expressions
   605 
   606 
   606 // In mandelbrot.scala I used complex (imaginary) numbers 
   607 // same examples using the internal regexes
   607 // and implemented the usual arithmetic operations for complex 
   608 val evil = "(a*)*b"
   608 // numbers.
   609 
   609 
   610 
   610 case class Complex(re: Double, im: Double) { 
   611 println("a" * 100)
   611   // represents the complex number re + im * i
   612 
   612   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im)
   613 ("a" * 10000).matches(evil)
   613   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im)
   614 ("a" * 10).matches(evil)
   614   def *(that: Complex) = Complex(this.re * that.re - this.im * that.im,
   615 ("a" * 10000).matches(evil)
   615                                  this.re * that.im + that.re * this.im)
   616 ("a" * 20000).matches(evil)
   616   def *(that: Double) = Complex(this.re * that, this.im * that)
   617 ("a" * 50000).matches(evil)
   617   def abs = Math.sqrt(this.re * this.re + this.im * this.im)
   618 
   618 }
   619 time_needed(1, ("a" * 50000).matches(evil))
   619 
       
   620 val test = Complex(1, 2) + Complex (3, 4)
       
   621 
       
   622 
       
   623 // ...to allow the notation n + m * i
       
   624 import scala.language.implicitConversions   
       
   625 
       
   626 val i = Complex(0, 1)
       
   627 implicit def double2complex(re: Double) = Complex(re, 0)
       
   628 
       
   629 val inum1 = -2.0 + -1.5 * i
       
   630 val inum2 =  1.0 +  1.5 * i