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 // |