简体   繁体   中英

Understanding Scala's flatmap type conversions

The docs for List state:

The type of the resulting collection is guided by the static type of list. This might cause unexpected results sometimes. For example:

// lettersOf will return a Seq[Char] of likely repeated letters, instead of a Set def lettersOf(words: Seq[String]) = words flatMap (word => word.toSet)

// lettersOf will return a Set[Char], not a Seq def lettersOf(words: Seq[String]) = words.toSet flatMap (word => word.toSeq)

I'm having a hard time understanding this. StringOps.toSet returns a Set of Char, so the first example ends up returning a Char Seq - fine. That makes sense. What I don't follow is why in the second example Scala constructs a Set instead of a Seq.

What exactly does "the resulting collection is guided by the static type of list" mean here?

Because of canBuildFrom method defined in Set class. As you can see in the ScalaDoc's CanBuildFrom trait it has thee type parameters CanBuildFrom[-From, -Elem, +To] where:

From - the type of the underlying collection that requests a builder to be created.
Elem - the element type of the collection to be created.
To - the type of the collection to be created.

Basiclly when you calling your flatMap function on the set it implicitly calls Set.canBuildFrom[Char] which return a Set[Char]

As for the static type. When Scala is tring to convert between collection types it uses this CanBuildFrom trait, which depends on the static type of your collection.

Updated for the comment

If we add -Xprint:typer to the scala command, we can see how Scala compiler after the typer phase resolves implicit method Set.canBuildFrom[Char] which is used to in flatMap method

def lettersOf(words: Seq[String]): scala.collection.immutable.Set[Char] = words.toSet[String].flatMap[Char, scala.collection.immutable.Set[Char]](((word: String) => scala.this.Predef.augmentString(word).toSeq))(immutable.this.Set.canBuildFrom[Char])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM