|      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.%  |