192 |
189 |
193 Bird("Sparrow") |
190 Bird("Sparrow") |
194 println(Bird("Sparrow")) |
191 println(Bird("Sparrow")) |
195 println(Bird("Sparrow").toString) |
192 println(Bird("Sparrow").toString) |
196 |
193 |
|
194 Bird("Sparrow").copy(name = "House Sparrow") |
|
195 |
|
196 def group(a : Animal) = a match { |
|
197 case Bird(_) => "It's a bird" |
|
198 case Mammal(_) => "It's a mammal" |
|
199 } |
|
200 |
197 |
201 |
198 // There is a very convenient short-hand notation |
202 // There is a very convenient short-hand notation |
199 // for constructors: |
203 // for constructors: |
200 |
204 |
201 class Fraction(x: Int, y: Int) { |
205 class Fraction(x: Int, y: Int) { |
202 def numer = x |
206 def numer = x |
203 def denom = y |
207 def denom = y |
204 } |
208 } |
205 |
209 |
206 val half = new Fraction(1, 2) |
210 val half = new Fraction(1, 2) |
|
211 half.numer |
207 |
212 |
208 case class Fraction(numer: Int, denom: Int) |
213 case class Fraction(numer: Int, denom: Int) |
209 |
214 |
210 val half = Fraction(1, 2) |
215 val half = Fraction(1, 2) |
211 |
216 |
|
217 half.numer |
212 half.denom |
218 half.denom |
213 |
219 |
214 |
220 |
215 // In mandelbrot.scala I used complex (imaginary) numbers |
221 // In mandelbrot.scala I used complex (imaginary) numbers |
216 // and implemented the usual arithmetic operations for complex |
222 // and implemented the usual arithmetic operations for complex |
226 def abs = Math.sqrt(this.re * this.re + this.im * this.im) |
232 def abs = Math.sqrt(this.re * this.re + this.im * this.im) |
227 } |
233 } |
228 |
234 |
229 val test = Complex(1, 2) + Complex (3, 4) |
235 val test = Complex(1, 2) + Complex (3, 4) |
230 |
236 |
|
237 import scala.language.postfixOps |
|
238 List(5,4,3,2,1).sorted.reverse |
|
239 |
231 // this could have equally been written as |
240 // this could have equally been written as |
232 val test = Complex(1, 2).+(Complex (3, 4)) |
241 val test = Complex(1, 2).+(Complex (3, 4)) |
233 |
242 |
234 // this applies to all methods, but requires |
243 // this applies to all methods, but requires |
235 import scala.language.postfixOps |
244 import scala.language.postfixOps |
268 balance |
277 balance |
269 } else throw new Error("insufficient funds") |
278 } else throw new Error("insufficient funds") |
270 } |
279 } |
271 |
280 |
272 // BUT since we are completely IMMUTABLE, this is |
281 // BUT since we are completely IMMUTABLE, this is |
273 // virtually of not concern to us. |
282 // virtually of no concern to us. |
274 |
283 |
275 |
284 |
276 |
285 |
277 // another example about Fractions |
286 // another example about Fractions |
278 import scala.language.implicitConversions |
287 import scala.language.implicitConversions |
279 import scala.language.reflectiveCalls |
288 import scala.language.reflectiveCalls |
280 |
289 |
281 |
|
282 case class Fraction(numer: Int, denom: Int) { |
290 case class Fraction(numer: Int, denom: Int) { |
283 override def toString = numer.toString + "/" + denom.toString |
291 override def toString = numer.toString + "/" + denom.toString |
284 |
292 |
285 def +(other: Fraction) = Fraction(numer + other.numer, denom + other.denom) |
293 def +(other: Fraction) = |
286 def /(other: Fraction) = Fraction(numer * other.denom, denom * other.numer) |
294 Fraction(numer * other.denom + other.numer * denom, |
|
295 denom * other.denom) |
|
296 def *(other: Fraction) = Fraction(numer * other.numer, denom * other.denom) |
287 } |
297 } |
288 |
298 |
289 implicit def Int2Fraction(x: Int) = Fraction(x, 1) |
299 implicit def Int2Fraction(x: Int) = Fraction(x, 1) |
290 |
|
291 |
300 |
292 val half = Fraction(1, 2) |
301 val half = Fraction(1, 2) |
293 val third = Fraction (1, 3) |
302 val third = Fraction (1, 3) |
294 |
303 |
295 half + third |
304 half + third |
296 half / third |
305 half * third |
297 |
306 |
298 (1 / 3) + half |
307 1 + half |
299 (1 / 2) + third |
308 |
|
309 |
300 |
310 |
301 |
311 |
302 // DFAs in Scala |
312 // DFAs in Scala |
303 //=============== |
313 //=============== |
304 import scala.util.Try |
314 import scala.util.Try |
315 case Nil => q |
325 case Nil => q |
316 case c::cs => deltas(delta(q, c), cs) |
326 case c::cs => deltas(delta(q, c), cs) |
317 } |
327 } |
318 |
328 |
319 def accepts(s: List[C]) : Boolean = |
329 def accepts(s: List[C]) : Boolean = |
320 Try(fins(deltas(start, s))) getOrElse false |
330 Try(fins(deltas(start, s))).getOrElse(false) |
321 } |
331 } |
322 |
332 |
323 // the example shown in the handout |
333 // the example shown in the handout |
324 abstract class State |
334 abstract class State |
325 case object Q0 extends State |
335 case object Q0 extends State |
357 fins: A => Boolean) { // final states |
367 fins: A => Boolean) { // final states |
358 |
368 |
359 // given a state and a character, what is the set of |
369 // given a state and a character, what is the set of |
360 // next states? if there is none => empty set |
370 // next states? if there is none => empty set |
361 def next(q: A, c: C) : Set[A] = |
371 def next(q: A, c: C) : Set[A] = |
362 Try(delta(q, c)) getOrElse Set[A]() |
372 Try(delta(q, c)).getOrElse(Set[A]()) |
363 |
373 |
364 def nexts(qs: Set[A], c: C) : Set[A] = |
374 def nexts(qs: Set[A], c: C) : Set[A] = |
365 qs.flatMap(next(_, c)) |
375 qs.flatMap(next(_, c)) |
366 |
376 |
367 // depth-first version of accepts |
377 // depth-first version of accepts |
395 |
405 |
396 |
406 |
397 // Q: Why the kerfuffle about the polymorphic types in DFAs/NFAs? |
407 // Q: Why the kerfuffle about the polymorphic types in DFAs/NFAs? |
398 // A: Subset construction. Here the state type for the DFA is |
408 // A: Subset construction. Here the state type for the DFA is |
399 // sets of states. |
409 // sets of states. |
|
410 |
400 |
411 |
401 def subset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = { |
412 def subset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = { |
402 DFA(nfa.starts, |
413 DFA(nfa.starts, |
403 { case (qs, c) => nfa.nexts(qs, c) }, |
414 { case (qs, c) => nfa.nexts(qs, c) }, |
404 _.exists(nfa.fins)) |
415 _.exists(nfa.fins)) |