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

前端 未结 5 995
一个人的身影
一个人的身影 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:47

    You might not be aware of it, but there's a flag for that: -Xlog-implicits. And this is what it says:

    scala> val barOpt2: Option[Bar] = fooOpt
    fromOptionToOption is not a valid implicit value for Some[Foo] => Option[Bar] because:
    incompatible: (from: Option[Foo])(implicit conversion: Foo => B)Option[B] does not match expected type Some[Foo] => Option[Bar]
    :16: error: type mismatch;
     found   : Some[Foo]
     required: Option[Bar]
           val barOpt2: Option[Bar] = fooOpt
                                      ^
    

    And there you go -- it doesn't know what type B must be. 0__ mentioned that this problem doesn't happen with invariant collections, and that makes some sense. In invariant collections, B must be exactly Bar, while for covariant collections it could be any subtype of Bar.

    So, why does val foo: Option[Foo] = Some(Bar(1)) work? Well, there's a flag for that too... -Ytyper-debug. Not for the weak, however, given the extreme verbosity.

    I waddled through anyway, comparing what happens in both cases, and the answer is rather simple... it's not the Option that is being converted in that case, but Bar! Remember, you declared an implicit conversion from Bar => Foo, so it is applying that conversion before passing the result to Some!

提交回复
热议问题