Scala: Making implicit conversion A->B work for Option[A] -> Option[B]

前端 未结 5 1003
一个人的身影
一个人的身影 2020-12-14 08:25

I\'m trying to write a function which re-uses the implicit conversions which I have for Object A -> Object B when they are wrapped in an Option in a generic way so that Opti

5条回答
  •  没有蜡笔的小新
    2020-12-14 08:40

    Indeed it's a very strange problem. I tried to use another type than Option, and it turns out that the problem is that Option is covariant in its type parameter. This works all:

    case class A[B](value: B)  // invariant in B
    
    case class X()
    case class Y()
    
    implicit def xtoy(x: X): Y = Y()
    implicit def ytox(x: Y): X = X()
    implicit def movea[U, V](from: A[U])(implicit view: U => V): A[V] =  A[V](from.value)
    
    def test(a: A[Y]) = "ok"
    test(A(X()))   // (1)
    val f = A(X())
    test(f)        // (2)
    

    But if instead I define A as

    case class A[+B](value: B)  // covariant in B
    

    The case (2) fails. Case (1) always succeeds, because Scala already converts X to Y before wrapping it in an A.

    Now that we know the problem source, you need to wait for a type guru to explain why this is actually a problem... The conversion is still valid, you see:

    askForY(movea(f))  // succeeds, even with A[+B]
    

提交回复
热议问题