progs/lecture5.scala
changeset 380 d19b0a50ceb9
parent 333 24bc76d97db2
child 383 c02929f2647c
equal deleted inserted replaced
379:5616b45d656f 380:d19b0a50ceb9
   168 val is = 
   168 val is = 
   169   (enum(LazyList(ZERO, ONE, CHAR('a'), CHAR('b')))
   169   (enum(LazyList(ZERO, ONE, CHAR('a'), CHAR('b')))
   170     .dropWhile(depth(_) < 3)
   170     .dropWhile(depth(_) < 3)
   171     .take(10).foreach(println))
   171     .take(10).foreach(println))
   172 
   172 
   173 
       
   174 
       
   175 // Polymorphic Types
       
   176 //===================
       
   177 
       
   178 // You do not want to write functions like contains, first, 
       
   179 // length and so on for every type of lists.
       
   180 
       
   181 
       
   182 def length_string_list(lst: List[String]): Int = lst match {
       
   183   case Nil => 0
       
   184   case _::xs => 1 + length_string_list(xs)
       
   185 }
       
   186 
       
   187 def length_int_list(lst: List[Int]): Int = lst match {
       
   188   case Nil => 0
       
   189   case x::xs => 1 + length_int_list(xs)
       
   190 }
       
   191 
       
   192 length_string_list(List("1", "2", "3", "4"))
       
   193 length_string_list(List(1, 2, 3, 4))
       
   194 
       
   195 // you can make the function parametric in type(s)
       
   196 
       
   197 def length[A](lst: List[A]): Int = lst match {
       
   198   case Nil => 0
       
   199   case x::xs => 1 + length(xs)
       
   200 }
       
   201 length[String](List("1", "2", "3", "4"))
       
   202 length(List(1, 2, 3, 4))
       
   203 
       
   204 
       
   205 def map[A, B](lst: List[A], f: A => B): List[B] = lst match {
       
   206   case Nil => Nil
       
   207   case x::xs => f(x)::map(xs, f) 
       
   208 }
       
   209 
       
   210 map(List(1, 2, 3, 4), (x: Int) => x.toString)
       
   211 
       
   212 
       
   213 
       
   214 // distinct / distinctBy
       
   215 
       
   216 val ls = List(1,2,3,3,2,4,3,2,1)
       
   217 ls.distinct
       
   218 
       
   219 // .minBy(_._2)
       
   220 // .sortBy(_._1)
       
   221 
       
   222 def distinctBy[B, C](xs: List[B], 
       
   223                      f: B => C, 
       
   224                      acc: List[C] = Nil): List[B] = xs match {
       
   225   case Nil => Nil
       
   226   case x::xs => {
       
   227     val res = f(x)
       
   228     if (acc.contains(res) distinctBy(xs, f, acc)  
       
   229     else x::distinctBy(xs, f, res::acc)
       
   230   }
       
   231 } 
       
   232 
       
   233 val cs = List('A', 'b', 'a', 'c', 'B', 'D', 'd')
       
   234 
       
   235 distinctBy(cs, (c:Char) => c.toUpper)
       
   236 
       
   237 // since 2.13
       
   238 
       
   239 cs.distinctBy((c:Char) => c.toUpper)
       
   240 
       
   241 
       
   242 // Type inference is local in Scala
       
   243 
       
   244 def id[T](x: T) : T = x
       
   245 
       
   246 val x = id(322)          // Int
       
   247 val y = id("hey")        // String
       
   248 val z = id(Set(1,2,3,4)) // Set[Int]
       
   249 
       
   250 id[+A, -B]
       
   251 
       
   252 // The type variable concept in Scala can get really complicated.
       
   253 //
       
   254 // - variance (OO)
       
   255 // - bounds (subtyping)
       
   256 // - quantification
       
   257 
       
   258 // Java has issues with this too: Java allows
       
   259 // to write the following incorrect code, and
       
   260 // only recovers by raising an exception
       
   261 // at runtime.
       
   262 
       
   263 // Object[] arr = new Integer[10];
       
   264 // arr[0] = "Hello World";
       
   265 
       
   266 
       
   267 // Scala gives you a compile-time error, which
       
   268 // is much better.
       
   269 
       
   270 var arr = Array[Int]()
       
   271 arr(0) = "Hello World"
       
   272 
   173 
   273 
   174 
   274 // (Immutable)
   175 // (Immutable)
   275 // Object Oriented Programming in Scala
   176 // Object Oriented Programming in Scala
   276 //
   177 //