3 ms·
flatMap [B, That] (f: (A) ⇒ Traversable[B])(implicit bf: CanBuildFrom[List[A], B, That]) : That ... tell me that doesn't make you want to run screaming It ma
by flatline 15y ago
flatMap [B, That] (f: (A) ⇒ Traversable[B])(implicit bf: CanBuildFrom[List[A], B, That]) : That
...
tell me that doesn't make you want to run screaming
It may not be great but I prefer this to a higher-order function in a dynamically typed language, where your only recourse may be to read the source code in depth to figure out valid arguments. I have run into this with some Scheme and JS libraries - better hope for good documentation! I really like Scala's type system.
In my brief foray with Scala a couple years back, the thing I remember being most frustrated by was that idiomatic Scala looks too much like idiomatic Perl in some cases. Sometimes blocks would be denoted by parens, sometimes by braces or nothing at all, and it was often hard to tell if you were inside a nested function or not. The underscore was also an unfortunate addition to the language. When I stepped away from it for a couple months and came back, the Scala I'd worked so hard to write "idiomatically" was no longer legible to me.
- gregwebs 15y agois that the same as Haskell's concatMap? concatMap :: (a -> [b]) -> [a] -> [b] There are some more general versions that may be a closer comparison: concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
- devonrt 15y agoThe great thing about the Haskell signature is that if you understand functional programming at all, it's fairly easy to understand, at least in my opinion. Scala's method signature requires knowledge of Scala's brand of functional programming, including mixins and implicits.
- richcollins 15y agoCan you explain wtf is going on here?
- cachemoney 15y agoThis whole thing is a bit disingenuous, because the type signature argued over is an alternate signature which no one uses, because it provides custom concatenation of Traversables. All of the provided collections have reasonable implementations of concatenation, so this implies you're inventing your own collection. Everyone uses the alternate form: flatMap [B] (f: (A) ⇒ Traversable[B]): CC[B]. Nevertheless, I'll attempt to explain the provided signature. If you understand Java generics, you should hopefully be able to understand this response. A, B, and That are type parameters/generics. So they can be filled in by any type. This flatMap method exists on a trait (think Java Interface) called Traversable[A]. Traversable is similar to Iterable in java. (f: (A) ⇒ Traversable[B]) means that this function takes one argument called f. That argument is a closure or anonymous function. The closure itself takes one argument of type A (an element in the parent Traversable[A]), and returns a Traversable[B], where B is an arbitrary type. Skipping ahead, flatMap returns an instance of That. But what's a That? It appears to be unspecified. This is where the "(implicit bf: CanBuildFrom[List[A], B, That])" makes it's appearance. Implicit parameters are like default arguments. "def foo(i: Int = 12)" will use the i if provided, else it will default to 12. "def foo(implicit i: Int)" will take the i given, else it will grab the first available Int in the containing scope. If you, "val c = 11; def foo(implicit i: Int) = i * 2", calling foo(1) yields 2, but calling foo() yields 22. The object bf is an object that provides an overridable custom definition of concatenation. So when you write your custom collection, you include an instance of CanBuildFrom[List[A], B, That] in the correct scope, and it gets used for the concatenation. CanBuildFrom's type parameters say that it exists in a List[A], takes a B, and returns a That. So yeah, in your implementation of bf, you could make it a new MyCanBuildFrom[List[A], B, FunkyCollection[B]], and do funky concatenation. Hope that helps.
- richcollins 15y agoI guess what I meant to ask is what is the point of this code - what operation is it performing.
- fizx 15y agoscala> List(1,2,3).flatMap(n => List(n, n*2)) res7: List[Int] = List(1, 2, 2, 4, 3, 6)
- robinst 15y agoLooking at the Scala API for List, I see the following: def flatMap [B] (f: (A) ⇒ GenTraversableOnce[B]): List[B] Seems nice and readable to me. The full declaration is below it, but this "use case" documentation is usually enough. http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List http://www.scala-lang.org/api/current/index.html#scala.colle...
- deleted 15y ago[deleted]