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