I wrote the following simple example to understand how the map method works:
object Main{
def main (args : Array[String]) = {
val test = "abc"
val t = Vector(97, 98, 99)
println(test.map(c => (c + 1))) //1 Vector(98, 99, 100)
println(test.map(c => (c + 1).toChar)) //2 bcd
println(t.map(i => (i + 1))) //3 Vector(98, 99, 100)
println(t.map(i => (i + 1).toChar)) //4 Vector(b, c, d)
};
}
I didn't quite understand why bcd is printed at //2
. Since every String is treated by Scala as being a Seq
I thought that test.map(c => (c + 1).toChar)
should have produced another Seq
. As //1
suggests Vector(b, c, d)
. But as you can see, it didn't. Why? How does it actually work?
This is a feature of Scala collections (String in this case is treated as a collection of characters). The real explanation is quite complex, and involves understanding of typeclasses (I guess, this is why Haskell was mentioned in the comment), but the simple explanation is, well, not quite hard.
The point is, Scala collections library authors tried very hard to avoid code duplication. For example, the map
function on String
is actually defined here: scala.collection.TraversableLike#map
. On the other hand, a naive approach to such task would make map
return TraversableLike
, not the original type the map
was called on (it was the String
). That's why they've came up with an approach that allows to avoid both code duplication and unnecessary type casting or too general return type.
Basically, Scala collections methods like map
produce the type that is as close to the type it was called at as possible. This is achieved using a typeclass called CanBuildFrom
. The full signature of the map
looks as follows:
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
There is a lot of explanations what is a typeclass and CanBuildFrom
around. I'd suggest looking here first: http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html#factoring-out-common-operations. Another good explanation is here: Scala 2.8 CanBuildFrom
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With