链隐式转换集合

时间:2016-07-05 10:09:59

标签: scala implicit-conversion

我无法进行隐式转换List [A] =>列表[B],给出隐式转换A => B.

有一个非常related question that has a solution but does not work for me。此外,这是一个很好的documentation for chaining implicits,我用它作为我的代码的基础。

我尝试在下面的代码中提出的观点是,链接implicits在所有预期的情况下都能正常工作,即使对于类似集合的对象,例如下面的Container,但集合失败了:

object ChainImplicits extends App{
  case class A(n: Int)
  implicit def toA(n: Int): A = A(n)

  case class B(m: Int, n: Int)
  implicit def aToB[T](a: T)(implicit f: T => A): B = B(a.n, a.n)

  case class C(m: Int, n: Int, o: Int) {
    def total = m + n + o
  }
  implicit def bToC[T](b: T)(implicit f: T => B): C = C(b.m, b.n, b.m + b.n)

  // works
  println(5.total)
  println(new A(5).total)
  println(new B(5, 5).total)
  println(new C(5, 5, 10).total)

  case class Container[T](value:T) {
    def map[B](f: T => B) = Container(f(value))
  }
  implicit def ContainerConv[A,B](container:Container[A])
                                 (implicit f: A => B): Container[B] = container.map(f)

  val container = Container(1)
  container.value.total //Works, as expected

  def containerCTotal(containerC: Container[C]) = containerC.value.total
  containerCTotal(container) //Works too!

  implicit def listConv[A,B](collection: List[A])
                            (implicit f: A => B): List[B] = collection.map(f)

  val list = List(1)
  def CTotals(list: List[C]) = list.map(_.total)
  CTotals(listConv(list)) //Explicit conversion works, finds the chain implicit conversions Int => C :)
  CTotals(list) //... but implicit does not :(

  def ATotals(list: List[A]) = list.map(_.total)
  ATotals(list) // Simple (non-chained) conversion of contained values does not work either :(
}

如何使这些最后的转化有效?

我还尝试了(已弃用的)视图边界,得到了相同的结果:

implicit def convert[B, A <% B](l: List[A]): List[B] = l map { a => a: B }

以防万一,编译错误是预期的:

type mismatch;
 found   : List[Int]
 required: List[ChainImplicits.C]
 CTotals(list) //... but implicit does not :(

同样适用于ATotals(list)

我在scala版本2.11.8和2.11.4上尝试过它。

更新

我在Andreas&#39;之后证实了评论基础问题与List协变有关。给上面的Container类提供协方差(即Container[+A])会使containerCTotal(container)之前有效的隐式转换失败。

0 个答案:

没有答案