9 //=====================  | 
    18 //=====================  | 
    10   | 
    19   | 
    11   | 
    20   | 
    12 // Extensions or How to Pimp your Library  | 
    21 // Extensions or How to Pimp your Library  | 
    13 //======================================  | 
    22 //======================================  | 
    14 //  | 
    23   | 
    15 // For example adding your own methods to Strings:  | 
    24 // For example adding your own methods to Strings:  | 
    16 // Imagine you want to increment strings, like  | 
    25 // Imagine you want to increment strings, like  | 
    17 //  | 
    26 //  | 
    18 //     "HAL".increment  | 
    27 //     "HAL".increment  | 
    19 //  | 
    28 //  | 
    20 // you can avoid ugly fudges, like a MyString, by  | 
    29 // you can avoid ugly fudges, like a MyString, by  | 
    21 // using implicit conversions.  | 
    30 // using extensions.  | 
    22   | 
    31   | 
    23 extension (s: String) { | 
    32 extension (s: String) { | 
    24   def increment = s.map(c => (c + 1).toChar)  | 
    33   def increment = s.map(c => (c + 1).toChar)  | 
    25 }  | 
    34 }  | 
    26   | 
    35   | 
    27 "HAL".increment  | 
    36 "HAL".increment  | 
    28   | 
    37   | 
    29   | 
    38   | 
    30   | 
    39   | 
         | 
    40 // a more relevant example  | 
    31   | 
    41   | 
    32 import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES} | 
    42 import scala.concurrent.duration.{TimeUnit,SECONDS,MINUTES} | 
    33   | 
    43   | 
    34 case class Duration(time: Long, unit: TimeUnit) { | 
    44 case class Duration(time: Long, unit: TimeUnit) { | 
    35   def +(o: Duration) =   | 
    45   def +(o: Duration) =   | 
    43   | 
    53   | 
    44 2.minutes + 60.seconds  | 
    54 2.minutes + 60.seconds  | 
    45 5.seconds + 2.minutes   //Duration(125, SECONDS )  | 
    55 5.seconds + 2.minutes   //Duration(125, SECONDS )  | 
    46   | 
    56   | 
    47   | 
    57   | 
         | 
    58 // Implicit Conversions  | 
         | 
    59 //=====================  | 
         | 
    60   | 
         | 
    61   | 
         | 
    62   | 
    48 // Regular expressions - the power of DSLs in Scala  | 
    63 // Regular expressions - the power of DSLs in Scala  | 
    49 //                                     and Laziness  | 
         | 
    50 //==================================================  | 
    64 //==================================================  | 
    51   | 
    65   | 
    52 abstract class Rexp  | 
    66 abstract class Rexp  | 
    53 case object ZERO extends Rexp                     // nothing  | 
    67 case object ZERO extends Rexp                     // nothing  | 
    54 case object ONE extends Rexp                      // the empty string  | 
    68 case object ONE extends Rexp                      // the empty string  | 
    55 case class CHAR(c: Char) extends Rexp             // a character c  | 
    69 case class CHAR(c: Char) extends Rexp             // a character c  | 
    56 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2  | 
    70 case class ALT(r1: Rexp, r2: Rexp) extends Rexp   // alternative  r1 + r2  | 
    57 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2    | 
    71 case class SEQ(r1: Rexp, r2: Rexp) extends Rexp   // sequence     r1 . r2    | 
    58 case class STAR(r: Rexp) extends Rexp             // star         r*  | 
    72 case class STAR(r: Rexp) extends Rexp             // star         r*  | 
    59   | 
    73   | 
         | 
    74 val r = STAR(CHAR('a')) | 
         | 
    75   | 
    60   | 
    76   | 
    61 // some convenience for typing in regular expressions  | 
    77 // some convenience for typing in regular expressions  | 
    62 import scala.language.implicitConversions      | 
    78 import scala.language.implicitConversions      | 
    63 import scala.language.reflectiveCalls   | 
    79 import scala.language.reflectiveCalls   | 
    64   | 
    80   | 
    74   def | (s: Rexp) = ALT(r, s)  | 
    90   def | (s: Rexp) = ALT(r, s)  | 
    75   def % = STAR(r)  | 
    91   def % = STAR(r)  | 
    76   def ~ (s: Rexp) = SEQ(r, s)  | 
    92   def ~ (s: Rexp) = SEQ(r, s)  | 
    77 }  | 
    93 }  | 
    78   | 
    94   | 
    79   | 
    95 val r1 = CHAR('a') | CHAR('b') | CHAR('c') | 
         | 
    96 val r2 = CHAR('a') ~  CHAR('b') | 
         | 
    97   | 
         | 
    98 val r3 : Rexp = "hello world"  | 
         | 
    99         | 
    80   | 
   100   | 
    81 //example regular expressions  | 
   101 //example regular expressions  | 
    82 val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"  | 
   102 val digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"  | 
    83 val sign = "+" | "-" | ""  | 
   103 val sign = "+" | "-" | ""  | 
    84 val number = sign ~ digit ~ digit.%   | 
   104 val number = sign ~ digit ~ digit.%   |