我正在尝试编写一些库函数来增强基本集合。大部分都进展顺利,但这个有问题。
class EnhancedGenTraversableLike[A, Repr <: GenTraversable[A]](self: GenTraversableLike[A, Repr]) {
def mapValuesStrict[T, U, R, That](f: U => R)(implicit ev: A <:< (T, U), bf: CanBuildFrom[Repr, (T, R), That]) = {
val b = bf(self.asInstanceOf[Repr])
b.sizeHint(self.size)
for ((k: T, v: U) <- self) b += k -> f(v)
b.result
}
}
implicit def enhanceGenTraversableLike[A, Repr <: GenTraversable[A]](self: GenTraversableLike[A, Repr]) = new EnhancedGenTraversableLike[A, Repr](self)
这是当我去使用它时发生的情况:
scala> List((1,2),(2,3),(3,4),(2,5)).mapValuesStrict((_:Int).toString)
res0: List[(Int, java.lang.String)] = List((1,2), (2,3), (3,4), (2,5))
scala> List((1,2),(2,3),(3,4),(2,5)).mapValuesStrict(x => x.toString)
<console>:13: error: missing parameter type
List((1,2),(2,3),(3,4),(2,5)).mapValuesStrict(x => x.toString)
^
因此,Scala 无法确定 x
的类型。
这个答案 表明 Scala 不使用一个参数来解决另一个参数,但是可以通过分离的参数列表解决问题。然而,在我的情况下,由于类型信息包含在隐式参数中,这并不容易。
有没有办法绕过这个问题,使我不必每次调用方法时都指定类型?
更新:根据Owen的建议,我最终创建了一个专门用于可遍历对的增强类。
class EnrichedPairGenTraversableLike[T, U, Repr <: GenTraversable[(T, U)]](self: GenTraversableLike[(T, U), Repr]) {
def mapValuesStrict[R, That](f: U => R)(implicit bf: CanBuildFrom[Repr, (T, R), That]) = {
val b = bf(self.asInstanceOf[Repr])
b.sizeHint(self.size)
for ((k: T, v: U) <- self) b += k -> f(v)
b.result
}
}
implicit def enrichPairGenTraversableLike[T, U, Repr <: GenTraversable[(T, U)]](self: GenTraversableLike[(T, U), Repr]) = new EnrichedPairGenTraversableLike(self)
GenTraversableLike[(T, U), Repr]
。正如您所展示的那样,这克服了问题,并且在概念上也非常清晰。 - dhg