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 |