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
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]