|     47  |     47  | 
|     48 val ls = List(1,2,3,3,2,4,3,2,1) |     48 val ls = List(1,2,3,3,2,4,3,2,1) | 
|     49 ls.distinct |     49 ls.distinct | 
|     50  |     50  | 
|     51  |     51  | 
|     52 def distinctBy[B, C](xs: List[B], f: B => C, acc: List[C] = Nil): List[B] = xs match { |     52 def distinctBy[B, C](xs: List[B],  | 
|         |     53                      f: B => C,  | 
|         |     54                      acc: List[C] = Nil): List[B] = xs match { | 
|     53   case Nil => Nil |     55   case Nil => Nil | 
|     54   case (x::xs) => { |     56   case x::xs => { | 
|     55     val res = f(x) |     57     val res = f(x) | 
|     56     if (acc.contains(res)) distinctBy(xs, f, acc)   |     58     if (acc.contains(res)) distinctBy(xs, f, acc)   | 
|     57     else x::distinctBy(xs, f, res::acc) |     59     else x::distinctBy(xs, f, res::acc) | 
|     58   } |     60   } | 
|     59 }  |     61 }  | 
|     60  |     62  | 
|         |     63 // distinctBy  with the identity function is  | 
|         |     64 // just distinct | 
|     61 distinctBy(ls, (x: Int) => x) |     65 distinctBy(ls, (x: Int) => x) | 
|     62  |     66  | 
|     63  |     67  | 
|     64 val cs = List('A', 'b', 'a', 'c', 'B', 'D', 'd') |     68 val cs = List('A', 'b', 'a', 'c', 'B', 'D', 'd') | 
|     65  |     69  | 
|     68  |     72  | 
|     69  |     73  | 
|     70 // Type inference is local in Scala |     74 // Type inference is local in Scala | 
|     71  |     75  | 
|     72 def id[T](x: T) : T = x |     76 def id[T](x: T) : T = x | 
|     73  |         | 
|     74  |     77  | 
|     75 val x = id(322)          // Int |     78 val x = id(322)          // Int | 
|     76 val y = id("hey")        // String |     79 val y = id("hey")        // String | 
|     77 val z = id(Set(1,2,3,4)) // Set[Int] |     80 val z = id(Set(1,2,3,4)) // Set[Int] | 
|     78  |     81  | 
|     83 // - variance (OO) |     86 // - variance (OO) | 
|     84 // - bounds (subtyping) |     87 // - bounds (subtyping) | 
|     85 // - quantification |     88 // - quantification | 
|     86  |     89  | 
|     87 // Java has issues with this too: Java allows |     90 // Java has issues with this too: Java allows | 
|     88 // to write the following, but raises an exception |     91 // to write the following incorrect code, and | 
|     89 // at runtime |     92 // only recovers by raising an exception | 
|     90  |     93 // at runtime. | 
|     91 //Object[] arr = new Integer[10]; |     94  | 
|     92 //arr[0] = "Hello World"; |     95 // Object[] arr = new Integer[10]; | 
|         |     96 // arr[0] = "Hello World"; | 
|     93  |     97  | 
|     94  |     98  | 
|     95 // Scala gives you a compile-time error |     99 // Scala gives you a compile-time error | 
|     96  |    100  | 
|     97 var arr = Array[Int]() |    101 var arr = Array[Int]() | 
|    110 abstract class Animal |    114 abstract class Animal | 
|    111 case class Bird(name: String) extends Animal |    115 case class Bird(name: String) extends Animal | 
|    112 case class Mammal(name: String) extends Animal |    116 case class Mammal(name: String) extends Animal | 
|    113 case class Reptile(name: String) extends Animal |    117 case class Reptile(name: String) extends Animal | 
|    114  |    118  | 
|    115 println(new Bird("Sparrow")) |    119 println(Bird("Sparrow")) | 
|    116 println(Bird("Sparrow").toString) |    120 println(Bird("Sparrow").toString) | 
|    117  |    121  | 
|    118  |    122  | 
|    119 // you can override methods |    123 // you can override methods | 
|    120 case class Bird(name: String) extends Animal { |    124 case class Bird(name: String) extends Animal { | 
|    136 val half = Fraction(1, 2) |    140 val half = Fraction(1, 2) | 
|    137  |    141  | 
|    138 half.denom |    142 half.denom | 
|    139  |    143  | 
|    140  |    144  | 
|    141 // in mandelbrot.scala I used complex (imaginary) numbers and implemented |    145 // In mandelbrot.scala I used complex (imaginary) numbers  | 
|    142 // the usual arithmetic operations for complex numbers |    146 // and implemented the usual arithmetic operations for complex  | 
|         |    147 // numbers. | 
|    143  |    148  | 
|    144 case class Complex(re: Double, im: Double) {  |    149 case class Complex(re: Double, im: Double) {  | 
|    145   // represents the complex number re + im * i |    150   // represents the complex number re + im * i | 
|    146   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im) |    151   def +(that: Complex) = Complex(this.re + that.re, this.im + that.im) | 
|    147   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im) |    152   def -(that: Complex) = Complex(this.re - that.re, this.im - that.im) | 
|    161  |    166  | 
|    162 List(5, 2, 3, 4).sorted |    167 List(5, 2, 3, 4).sorted | 
|    163 List(5, 2, 3, 4) sorted |    168 List(5, 2, 3, 4) sorted | 
|    164  |    169  | 
|    165  |    170  | 
|    166 // to allow the notation n + m * i |    171 // ...to allow the notation n + m * i | 
|    167 import scala.language.implicitConversions    |    172 import scala.language.implicitConversions    | 
|         |    173  | 
|    168 object i extends Complex(0, 1) |    174 object i extends Complex(0, 1) | 
|    169 implicit def double2complex(re: Double) = Complex(re, 0) |    175 implicit def double2complex(re: Double) = Complex(re, 0) | 
|    170  |    176  | 
|    171  |    177  | 
|    172 val inum1 = -2.0 + -1.5 * i |    178 val inum1 = -2.0 + -1.5 * i | 
|    173 val inum2 =  1.0 +  1.5 * i |    179 val inum2 =  1.0 +  1.5 * i | 
|    174  |    180  | 
|    175  |    181  | 
|    176  |    182  | 
|    177 // all is public by default....so no public |    183 // All is public by default....so no public is needed. | 
|    178 // you can have the usual restrictions about private values |    184 // You can have the usual restrictions about private  | 
|    179 // and methods, if you are MUTABLE(!!!) |    185 // values and methods, if you are MUTABLE !!! | 
|    180  |    186  | 
|    181 case class BankAccount(init: Int) { |    187 case class BankAccount(init: Int) { | 
|    182  |    188  | 
|    183   private var balance = init |    189   private var balance = init | 
|    184  |    190  | 
|    205  |    211  | 
|    206  |    212  | 
|    207 // A is the state type |    213 // A is the state type | 
|    208 // C is the input (usually characters) |    214 // C is the input (usually characters) | 
|    209  |    215  | 
|    210 case class DFA[A, C](start: A,               // starting state |    216 case class DFA[A, C](start: A,              // starting state | 
|    211                      delta: (A, C) => A,     // transition function |    217                      delta: (A, C) => A,    // transition function | 
|    212                      fins:  A => Boolean) {  // final states |    218                      fins:  A => Boolean) { // final states (Set) | 
|    213  |    219  | 
|    214   def deltas(q: A, s: List[C]) : A = s match { |    220   def deltas(q: A, s: List[C]) : A = s match { | 
|    215     case Nil => q |    221     case Nil => q | 
|    216     case c::cs => deltas(delta(q, c), cs) |    222     case c::cs => deltas(delta(q, c), cs) | 
|    217   } |    223   } | 
|    246 dfa.accepts("abaaa".toList)     // true |    252 dfa.accepts("abaaa".toList)     // true | 
|    247 dfa.accepts("bbabaab".toList)   // true |    253 dfa.accepts("bbabaab".toList)   // true | 
|    248 dfa.accepts("baba".toList)      // false |    254 dfa.accepts("baba".toList)      // false | 
|    249 dfa.accepts("abc".toList)       // false |    255 dfa.accepts("abc".toList)       // false | 
|    250  |    256  | 
|    251 // another DFA test with a Sink state |    257 // another DFA with a Sink state | 
|    252 abstract class S |    258 abstract class S | 
|    253 case object S0 extends S |    259 case object S0 extends S | 
|    254 case object S1 extends S |    260 case object S1 extends S | 
|    255 case object S2 extends S |    261 case object S2 extends S | 
|    256 case object Sink extends S |    262 case object Sink extends S | 
|    257  |    263  | 
|    258 // transition function with a sink state |    264 // transition function with a sink state | 
|    259 val sigma : (S, Char) :=> S =  |    265 val sigma : (S, Char) => S =  | 
|    260   { case (S0, 'a') => S1 |    266   { case (S0, 'a') => S1 | 
|    261     case (S1, 'a') => S2 |    267     case (S1, 'a') => S2 | 
|    262     case _ => Sink |    268     case _ => Sink | 
|    263   } |    269   } | 
|    264  |    270  | 
|    266  |    272  | 
|    267 dfa2.accepts("aa".toList)        // true |    273 dfa2.accepts("aa".toList)        // true | 
|    268 dfa2.accepts("".toList)          // false |    274 dfa2.accepts("".toList)          // false | 
|    269 dfa2.accepts("ab".toList)        // false |    275 dfa2.accepts("ab".toList)        // false | 
|    270  |    276  | 
|         |    277 //  we could also have a dfa for numbers | 
|         |    278 val sigmai : (S, Int) => S =  | 
|         |    279   { case (S0, 1) => S1 | 
|         |    280     case (S1, 1) => S2 | 
|         |    281     case _ => Sink | 
|         |    282   } | 
|         |    283  | 
|         |    284 val dfa3 = DFA(S0, sigmai, Set[S](S2)) | 
|         |    285  | 
|         |    286 dfa3.accepts(List(1, 1))        // true | 
|         |    287 dfa3.accepts(Nil)               // false | 
|         |    288 dfa3.accepts(List(1, 2))        // false | 
|         |    289  | 
|    271  |    290  | 
|    272  |    291  | 
|    273  |    292  | 
|    274 // NFAs (Nondeterministic Finite Automata) |    293 // NFAs (Nondeterministic Finite Automata) | 
|    275  |    294  | 
|    276  |    295  | 
|    277 case class NFA[A, C](starts: Set[A],           // starting states |    296 case class NFA[A, C](starts: Set[A],          // starting states | 
|    278                      delta: (A, C) => Set[A],  // transition function |    297                      delta: (A, C) => Set[A], // transition function | 
|    279                      fins:  A => Boolean) {    // final states  |    298                      fins:  A => Boolean) {   // final states  | 
|    280  |    299  | 
|    281   // given a state and a character, what is the set of  |    300   // given a state and a character, what is the set of  | 
|    282   // next states? if there is none => empty set |    301   // next states? if there is none => empty set | 
|    283   def next(q: A, c: C) : Set[A] =  |    302   def next(q: A, c: C) : Set[A] =  | 
|    284     Try(delta(q, c)) getOrElse Set[A]()  |    303     Try(delta(q, c)) getOrElse Set[A]()  | 
|    285  |         | 
|    286   def nexts(qs: Set[A], c: C) : Set[A] = |         | 
|    287     qs.flatMap(next(_, c)) |         | 
|    288  |    304  | 
|    289   // depth-first version of accepts |    305   // depth-first version of accepts | 
|    290   def search(q: A, s: List[C]) : Boolean = s match { |    306   def search(q: A, s: List[C]) : Boolean = s match { | 
|    291     case Nil => fins(q) |    307     case Nil => fins(q) | 
|    292     case c::cs => next(q, c).exists(search(_, cs)) |    308     case c::cs => next(q, c).exists(search(_, cs)) | 
|    314 nfa.accepts("aaaaabbb".toList)       // true |    330 nfa.accepts("aaaaabbb".toList)       // true | 
|    315 nfa.accepts("aaaaabbbaaa".toList)    // false |    331 nfa.accepts("aaaaabbbaaa".toList)    // false | 
|    316 nfa.accepts("ac".toList)             // false |    332 nfa.accepts("ac".toList)             // false | 
|    317  |    333  | 
|    318  |    334  | 
|    319 // Q: Why the kerfuffle about the polymorphic types in DFAs/NFAs |    335 // Q: Why the kerfuffle about the polymorphic types in DFAs/NFAs? | 
|    320 // A: Subset construction |    336 // A: Subset construction | 
|    321  |    337  | 
|    322 def subset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = { |    338 def subset[A, C](nfa: NFA[A, C]) : DFA[Set[A], C] = { | 
|    323   DFA(nfa.starts,  |    339   DFA(nfa.starts,  | 
|    324       { case (qs, c) => nfa.nexts(qs, c) },  |    340       { case (qs, c) => nfa.nexts(qs, c) },  |