【问题标题】:Scala method to convert generic Collection转换泛型集合的 Scala 方法
【发布时间】:2017-07-12 10:02:12
【问题描述】:

如何使用 map 方法创建一个方法,该方法采用通用 Collection M[A] 和从 AB 的函数并返回 Collection M[B]

类似: def convert[A, M[X] <: Traversable[X], B](in: M[A], f: A => B): M[B] = in.map(f)

上面的方法编译失败:type mismatch; found : Traversable[B] required: M[B]。由于Traversable[A].map(f: A =&gt; B) 的静态类型是Traversable[B],正如Oleg Pyzhcov 所指出的那样

注意:此方法的目的不仅仅是映射集合,这只是一种简化。

【问题讨论】:

  • 您发布的方法有什么问题?
  • 方法编译失败:类型不匹配;找到:需要 Traversable[B]:M[B]
  • 请将其包含在您的问题中。它将在未来简化搜索。
  • 要完全理解下面提供的这个问题的答案,我必须阅读这篇文章docs.scala-lang.org/overviews/core/…,这可能对将来面临类似任务的其他人有用。

标签: scala scala-collections


【解决方案1】:

map的完整签名是

def map[B, That](f: (A) ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That

因此,您需要从调用站点提供 CanBuildFrom,并确保使用以 Like 结尾并具有两个类型参数的集合特征将 Repr 推断为您的具体类型 M[A] >

import scala.collection.generic.CanBuildFrom
import scala.collection.TraversableLike
import scala.language.higherKinds

def convert[M[x] <: TraversableLike[x, M[x]], A, B](
    in: M[A],
    f: A => B
)(implicit
  cbf: CanBuildFrom[M[A], B, M[B]]
 ): M[B] = in.map(f)(cbf)

【讨论】:

  • 我和上面的@talex 有同样的评论:如果M[X] 扩展Traversable[X] 那么它已经支持从TraversableLike 继承的map。那么为什么不in.map(f) 呢?
  • @AlexanderArendar Traversable[A].map(f: A =&gt; B) 的静态类型是 Traversable[B],而不是作者想要的 M[B]
  • @Oleg Pyzhcov 这正是我想要的!谢谢!我尝试将implicitly[CanBuildFrom[M[A], B, M[B]]] 传递给in.map,但没有成功
  • @DanielReigada 是的,你的方法不知道在哪里可以找到 M[_] 的一个,直到你将它作为隐式参数提供。
猜你喜欢
  • 1970-01-01
  • 2020-12-03
  • 2020-06-16
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-21
相关资源
最近更新 更多