Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding String in Scala and the map method

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?

like image 969
St.Antario Avatar asked Mar 11 '23 21:03

St.Antario


1 Answers

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

like image 167
Haspemulator Avatar answered Mar 15 '23 03:03

Haspemulator