progs/lecture5.scala
changeset 494 253d1ccb65de
parent 482 769bda18a43d
equal deleted inserted replaced
493:244df77507c2 494:253d1ccb65de
     1 // Scala Lecture 5
     1 // Scala Lecture 5
     2 //=================
     2 //=================
     3 
     3 
     4 for (n <- (1 to 10).toList) yield {
     4 def foo(n: Int) = ???
     5   val add = 10
     5 
     6   n + add
     6 fop(10)
     7 }
     7 
     8 
     8 List.fill(1)(100)
     9 println(add)
       
    10 
       
    11 List(1,2,3,4).sum
       
    12 
       
    13 // extension methods
       
    14 // implicit conversions
       
    15 // (Immutable) OOP
     9 // (Immutable) OOP
    16 
       
    17 // Cool Stuff in Scala
       
    18 //=====================
       
    19 
       
    20 
       
    21 // Extensions or How to Pimp your Library
       
    22 //======================================
       
    23 
       
    24 // For example adding your own methods to Strings:
       
    25 // Imagine you want to increment strings, like
       
    26 //
       
    27 //     "HAL".increment
       
    28 //
       
    29 // you can avoid ugly fudges, like a MyString, by
       
    30 // using extensions.
       
    31 
       
    32 extension (s: String) {
       
    33   def increment = s.map(c => (c + 1).toChar)
       
    34 }
       
    35 
       
    36 "HAL".increment
       
    37 
       
    38 
       
    39 
       
    40 // a more relevant example
       
    41 
       
    42 import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES}
       
    43 
       
    44 case class Duration(time: Long, unit: TimeUnit) {
       
    45   def +(o: Duration) = 
       
    46     Duration(time + unit.convert(o.time, o.unit), unit)
       
    47 }
       
    48 
       
    49 extension (that: Int) {
       
    50   def seconds = Duration(that, SECONDS)
       
    51   def minutes = Duration(that, MINUTES)
       
    52 }
       
    53 
       
    54 2.minutes + 60.seconds
       
    55 5.seconds + 2.minutes   //Duration(125, SECONDS )
       
    56 
       
    57 
       
    58 // Implicit Conversions
       
    59 //=====================
       
    60 
       
    61 
       
    62 
       
    63 // Regular expressions - the power of DSLs in Scala
       
    64 //==================================================
       
    65 
       
    66 abstract class Rexp
       
    67 case object ZERO extends Rexp                     // nothing
       
    68 case object ONE extends Rexp                      // the empty string
       
    69 case class CHAR(c: Char) extends Rexp             // a character c
       
    70 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2
       
    71 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2  
       
    72 case class STAR(r: Rexp) extends Rexp             // star         r*
       
    73 
       
    74 val r = STAR(CHAR('a'))
       
    75 
       
    76 
       
    77 // some convenience for typing in regular expressions
       
    78 import scala.language.implicitConversions    
       
    79 import scala.language.reflectiveCalls 
       
    80 
       
    81 def charlist2rexp(s: List[Char]): Rexp = s match {
       
    82   case Nil => ONE
       
    83   case c::Nil => CHAR(c)
       
    84   case c::s => SEQ(CHAR(c), charlist2rexp(s))
       
    85 }
       
    86 
       
    87 given Conversion[String, Rexp] = (s => charlist2rexp(s.toList))
       
    88 
       
    89 extension (r: Rexp) {
       
    90   def | (s: Rexp) = ALT(r, s)
       
    91   def % = STAR(r)
       
    92   def ~ (s: Rexp) = SEQ(r, s)
       
    93 }
       
    94 
       
    95 val r1 = CHAR('a') | CHAR('b') | CHAR('c')
       
    96 val r2 = CHAR('a') ~  CHAR('b')
       
    97 
       
    98 val r3 : Rexp = "hello world"
       
    99       
       
   100 
       
   101 //example regular expressions
       
   102 val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
       
   103 val sign = "+" | "-" | ""
       
   104 val number = sign ~ digit ~ digit.% 
       
   105 
       
   106 
       
   107 
       
   108 
    10 
   109 // Object Oriented Programming in Scala
    11 // Object Oriented Programming in Scala
   110 // =====================================
    12 // =====================================
   111 
    13 
   112 
    14 
   160 
    62 
   161 // works with case classes
    63 // works with case classes
   162 half match {
    64 half match {
   163   case Fraction(x, y) => x / y
    65   case Fraction(x, y) => x / y
   164 }
    66 }
   165 
       
   166 
       
   167 // In mandelbrot.scala I used complex (imaginary) numbers 
       
   168 // and implemented the usual arithmetic operations for complex 
       
   169 // numbers.
       
   170 
       
   171 case class Complex(re: Double, im: Double) { 
       
   172   // represents the complex number re + im * i
       
   173   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im)
       
   174   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im)
       
   175   def *(that: Complex) = Complex(this.re * that.re - this.im * that.im,
       
   176                                  this.re * that.im + that.re * this.im)
       
   177   def *(that: Double) = Complex(this.re * that, this.im * that)
       
   178   def abs = Math.sqrt(this.re * this.re + this.im * this.im)
       
   179 }
       
   180 
       
   181 // usual way to reference methods
       
   182 //object.method(....)
       
   183 
       
   184 val test = Complex(1, 2) + (Complex (3, 4))
       
   185 
       
   186 
       
   187 import scala.language.postfixOps
       
   188 (List(5,4,3,2,1) sorted) reverse
       
   189 
       
   190 // this could have equally been written as
       
   191 val test = Complex(1, 2).+(Complex (3, 4))
       
   192 
       
   193 // this applies to all methods, but requires
       
   194 import scala.language.postfixOps
       
   195 
       
   196 List(5, 2, 3, 4).sorted
       
   197 List(5, 2, 3, 4) sorted
       
   198 
       
   199 
       
   200 // ...to allow the notation n + m * i
       
   201 import scala.language.implicitConversions   
       
   202 
       
   203 val i = Complex(0, 1)
       
   204 
       
   205 given Conversion[Double, Complex] = (re => Complex(re, 0))
       
   206 
       
   207 val inum1 = -2.0 + -1.5 * i
       
   208 val inum2 =  1.0 +  1.5 * i
       
   209 
    67 
   210 
    68 
   211 
    69 
   212 // All is public by default....so no public is needed.
    70 // All is public by default....so no public is needed.
   213 // You can have the usual restrictions about private 
    71 // You can have the usual restrictions about private 
   487 
   345 
   488 // 1st idea: enumerate them all in a Set
   346 // 1st idea: enumerate them all in a Set
   489 // up to a level
   347 // up to a level
   490 
   348 
   491 def enuml(l: Int, s: String) : Set[Rexp] = l match {
   349 def enuml(l: Int, s: String) : Set[Rexp] = l match {
   492   case 0 => Set(ZERO, ONE) ++ s.map(CHAR).toSet
   350   case 0 => Set(ZERO, ONE) ++ s.map(CHAR(_)).toSet
   493   case n =>  
   351   case n =>  
   494     val rs = enuml(n - 1, s)
   352     val rs = enuml(n - 1, s)
   495     rs ++
   353     rs ++
   496     (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) ++
   354     (for (r1 <- rs; r2 <- rs) yield ALT(r1, r2)) ++
   497     (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) ++
   355     (for (r1 <- rs; r2 <- rs) yield SEQ(r1, r2)) ++