Skip to content

Commit 27066b4

Browse files
committed
finish l2 & add test src_scala
1 parent 19e5c33 commit 27066b4

File tree

1 file changed

+93
-1
lines changed

1 file changed

+93
-1
lines changed

reactive-programming.org

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class Counter extends ActionListener {
5252
- Handlers of events are also first-class
5353
- Complex handlers can be composed from primitive ones
5454
** Recap: Functions and Pattern Matching
55+
- Recap: Case Classes
56+
Case classes are Scala's preferred way to define complex data.
5557
- Representation of JSON in Scala
5658
#+begin_src scala
5759
abstract class JSON
@@ -62,7 +64,6 @@ case class JStr (str: String) extends JSON
6264
case class JBool (b: Boolean) extends JSON
6365
case object JNull extends JSON
6466
#+end_src
65-
#+NAME: Example
6667
#+begin_src scala
6768
val data = JObj(Map(
6869
"firstName" -> JStr("John"),
@@ -80,3 +81,94 @@ val data = JObj(Map(
8081
"type" -> JStr("fax"), "number" -> JStr("646 555-4567")
8182
)) )) ))
8283
#+end_src scala
84+
- Pattern Matching
85+
Here's a method that returns the string representation JSON data:
86+
#+begin_src scala
87+
def show(json: JSON): String = json match {
88+
case JSeq(elems) =>
89+
"[" + (elems map show mkString ",") + "]"
90+
case JObj(bindings) =>
91+
val assocs = bindings map {
92+
case (key, value) => "\"" + key + "\": " + show(value)
93+
}
94+
"{" + (assocs mkString ", ") + "}"
95+
case JNum(num) => num.toString
96+
case JStr(str) => '\"' + str + '\"'
97+
case JBool(b) => b.toString
98+
case JNull => "null"
99+
}
100+
#+end_src scala
101+
- Functions Are Objects
102+
In Scala, every concrete type is the type of some class or trait.
103+
104+
The function type is no exception. A type like
105+
106+
src_scala{JBinding => String}
107+
108+
is just a shorthand for
109+
110+
src_scala{scala.Function1[JBinding, String]}
111+
112+
where =scala.Function1= is a trait and =JBinding= and =String= are its type arguments.
113+
- The Function1 Trait
114+
Here's an outline of that =Function1=:
115+
#+begin_src scala
116+
trait Function[-A, +R] {
117+
def apply(x: A): R
118+
}
119+
#+end_src
120+
The pattern matching block
121+
#+begin_src scala
122+
{ case (key, value)=> key + ": " + value }
123+
#+end_src
124+
expands to the =Function1= instance
125+
#+begin_src scala
126+
new Function1[JBinding, String] {
127+
def apply(x: JBinding) = x match {
128+
case (key, value) => key + ": " + show(value)
129+
}
130+
}
131+
#+end_src
132+
- Subclassing Functions
133+
One nice aspect of functions being traits is that we can subclass the function type.
134+
135+
For instance, maps are functions from keys to values:
136+
137+
src_scala{trait Map[Key, Value] extends (Key => Value) ...}
138+
139+
Sequences are functions from =int= indices to values:
140+
141+
src_scala{trait Seq[Elem] extends Int => Elem}
142+
143+
That's why we can write
144+
145+
=elems(i)=
146+
147+
for sequence (and array) indexing.
148+
- Partial Functions
149+
#+begin_src scala
150+
val f: PartialFunction[String, String] = { case "ping" => "pong"}
151+
f.isDefinedAt("ping") // true
152+
f.isDefinedAt("pong") // false
153+
#+end_src
154+
The partial function trait is defined as follows:
155+
#+begin_src scala
156+
trait PartialFunction[-A, +R] extends Function1[-A, +R] {
157+
def apply(x: A): R
158+
def isDefinedAt(x: A): R
159+
}
160+
#+end_src
161+
- Partial Function Objects
162+
If the expected type is a =PartialFunction=, the Scala compiler willl expand src_scala{{ case "ping" => "pong" }}
163+
164+
as follows:
165+
#+begin_src scala
166+
new PartialFunction[String, String] {
167+
...
168+
def isDefinedAt(x: String) = x match {
169+
case "ping" => true
170+
case _ => false
171+
}
172+
}
173+
#+end_src
174+
Note: =isDefinedAt= will only be determined by the outmost pattern

0 commit comments

Comments
 (0)