Вот подсказка:
scala> val fooOpt: Option[Bar] = Option(Foo(1))
fooOpt: Option[Bar] = Some(Bar(1))
И еще:
scala> implicit def foobar(x: String): Int = augmentString(x).toInt
foobar: (x: String)Int
scala> val y: Option[String] = Option(1)
y: Option[String] = Some(1)
scala> val y: Option[Int] = Option("1")
y: Option[Int] = Some(1)
Похоже на законную нечетную ошибку. Я бы открыл меньший тестовый пример и открыл проблему (или искал ее в JIRA).
В сторону:
Вы можете использовать некоторую теорию категорий для обработки множества различных типов вещей "Option-ish".
package object fun {
trait Functor[Container[_]] {
def fmap[A,B](x: Container[A], f: A => B): Container[B]
}
object Functor {
implicit object optionFunctor extends Functor[Option] {
override def fmap[A,B](x: Option[A], f: A => B): Option[B] = x map f
}
// Note: With some CanBuildFrom magic, we can support Traversables here.
}
implicit def liftConversion[F[_], A, B](x: F[A])(implicit f: A => B, functor: Functor[F]): F[B] =
functor.fmap(x,f)
}
Это немного сложнее, так как вы отображаете некоторую теорию категорий FP на проблему, но это более общее решение для переноса неявных разговоров в контейнеры по мере необходимости. Обратите внимание, как они объединяются в цепочку, используя один неявный метод диалога, который принимает более ограниченный неявный аргумент.
ТАКЖЕ, это должно заставить работать примеры:
scala> val tmp = Option(Foo(1))
tmp: Option[Foo] = Some(Foo(1))
scala> val y: Option[Bar] = tmp
y: Option[Bar] = Some(Bar(1))
И сделайте использование Some
более опасным:
scala> val tmp = Some(Foo(1))
tmp: Some[Foo] = Some(Foo(1))
scala> val y: Option[Bar] = tmp
<console>:25: error: could not find implicit value for parameter functor: fun.Functor[Some]
val y: Option[Bar] = tmp
^
Это говорит о том, что дисперсия является критической и взаимодействует с последствиями. Я предполагаю, что вы столкнулись с очень редкой, возможно, трудно исправить ошибкой, которую можно избежать, используя другие методы.