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) },  |