我正在尝试创建一个隐式转换器,它将使用当前在 (eg. A => B) 范围内的隐式转换器,并且能够将任何类型的 Traversable[A] 转换为 Traversable[B]

到目前为止,我得到了:

implicit def convertLists[A, B](from: Traversable[A])(implicit conv: A => B): Traversable[B] = from.map(conv)

但是,这不适用于:
val listOfB: List[B] = convertLists(List[A]())

如果我将 Traversable 更改为 List ,则它可以正常工作,例如:
implicit def convertLists[A, B](from: List[A])(implicit conv: A => B): List[B] = from.map(conv)

我是否需要添加任何其他内容以允许转换器接受 Traversable 的任何子类?

最佳答案

您已明确定义 convertLists 以返回 Traversable[B]Traversable 不是 List 的子类型(它是它的父类(super class)型),所以 convertLists ( Traversable ) 的结果不能是 listOfB ( List ) 的返回类型。

如果使用 convertLists ,则可以定义 CanBuildFrom 以根据其参数类型推断结果类型:

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

// `CC` is some concrete subtype of `Traversable`
// `That` is an automatically inferred result collection type
implicit def convertLists[A, B, CC[T] <: TraversableLike[T, CC[T]], That](
  from: CC[A]
)(
  implicit
    conv: A => B,
    // witness that it's possible to build
    // a collection with elements `B` from a collection `CC[A]`,
    // and compute the resulting collection type `That`
    bf: CanBuildFrom[CC[A], B, That]
): That = from.map(conv)

现在假设 AB 的简单定义如下
case class A(i: Int)
case class B(i: Int)
implicit def aisb(a: A): B = B(a.i)

以下工作:
val listOfB: List[B] = convertLists(List[A](A(1)))

而且您不必显式调用 convertLists:
val listOfB2: List[B] = List[A](A(1))

关于scala - Scala 中 Traversable 内容的隐式转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36130976/

10-09 02:52