4

我想实现一个方法,它接受一个元素类型的序列并返回一个不同元素类型的序列。我怎样才能一般地做到这一点,以便返回相同的 Sequence 子类?

我的方法目前看起来像这样:

def lookerUpper(ids : Seq[String], someOtherInfo : Int) : Seq[UsefulData] = {
    ... retrieve data for each id ...
}

我希望它更通用,以便传入任何类型的(字符串)序列也是返回的(UsefulData)序列类型。尤其是矢量和列表,或者我们可以做到的一般性。

这可以用 Scala 的类型系统来表达吗?“返回与此参数相同的类型,但类型参数不同。”

4

1 回答 1

3

要获得完整的答案,您应该查看我关于构建器的相当长的问题和答案(注意:截至 2012 年 9 月,Miles 的替代版本在 2.9 或最新的 2.10 中都不起作用)。

这是一个帮助您入门的框架(请注意显式和隐式参数块的奇怪格式,以避免在 SO 上显示过长的行):

import collection.generic.CanBuildFrom

case class UsefulData(data: Int) {}

def lookerUpper[C[String]](
  ids: C[String], someOtherInfo: Int
)(
  implicit cbf: CanBuildFrom[C[String],UsefulData,C[UsefulData]],
  ev: C[String] => Iterable[String]
): C[UsefulData] = {
  val b = cbf()
  val i = ev(ids)
  i.foreach{ s => b += UsefulData(s.length + someOtherInfo) }
  b.result 
}

并观察它是否有效:

scala> lookerUpper(Vector("salmon","cod"),2)
res0: scala.collection.immutable.Vector[UsefulData] = 
  Vector(UsefulData(8), UsefulData(5))

scala> lookerUpper(Array("salmon","cod"),2)
res1: Array[UsefulData] = 
  Array(UsefulData(8), UsefulData(5))

编辑:如果您只关心TraversableLikeArray不是)的子类,并且您将使用标准收集操作来完成所有工作,那么您可以使用Luigi 指出的 8609398 的答案。(也许我应该把这个答案作为另一个视角移到那里。)

于 2012-09-19T18:53:06.737 回答