我只是查看了List::map
方法声明,并因其并发症而感到困惑。以下是它的外观:
final override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[List[A], B, That]): That = {
好吧,我理解implicit
是什么(据我所知,基于trait CanBuildFrom
的类型类将由编译器自动引入,如果在范围内)。但That
在这里应该是什么意思?
我理解map(f: A => B)
是一个将每个函数f: A => B
映射到相应的monadic值List(A)
和List(B)
之间的函数的函数。所以我希望看到返回类型为List[B]
。
Option
的实际情况。
def map[B](f: A => B): Option[B]
List
和Option
都是monad。 List
的诀窍是什么?
答案 0 :(得分:3)
映射集合可以导致相同的集合(仅使用不同类型参数化),但不必。它可以产生完全不同的集合。例如,
val myMap = Map("firstName" -> "foo", "lastName" -> "bar")
val result = myMap map (_._1.length)
我们从Map[String, String]
开始,最后以Iterable[Int]
结束。这就是Traversable
s(注意Traversable
是一个“抽象特征”而TraversableLike
是一个“实现特征”)的原因,这个隐式构建器叫CanBuildFrom
。 Option
不是Traversable
,并且不需要所有这些转换机制 - 我们知道映射Option
始终会产生Option
。
在map
上执行Traversable
时,编译器会在随播对象中找到类型为CanBuildFrom
的对应值(例如,here's为List的对象值)。如果找不到任何内容,它将会超过一级等。请查看docs(在页面上找到“CanBuildFrom trait”并从那里开始)。
答案 1 :(得分:2)
您可以阅读有关这些集合here的体系结构的信息。我认为它用于了解操作的正确返回类型。例如,当您在toSet
上致电List
时,隐式CanBuildFrom[List[A], B, Seq[A]]
必须在范围内...