EitherT[Option, ?, ?]] can't be used as a bifunctor
strokyl opened this issue · comments
With scala 2.13.12
and cats-core 2.10.0
type MyBifunctor[A, B] = EitherT[Option, A, B]
val myByFunctor = implicitly[Bifunctor[MyBifunctor]]
Does not compile :
ambiguous implicit values:
both method catsDataBitraverseForEitherT in class EitherTInstances1 of type [F[_]](implicit F: cats.Traverse[F]): cats.Bitraverse[[β$69$, γ$70$]cats.data.EitherT[F,β$69$,γ$70$]]
and method catsDataBifunctorForEitherT in class EitherTInstances of type [F[_]](implicit F: cats.Functor[F]): cats.Bifunctor[[β$15$, γ$16$]cats.data.EitherT[F,β$15$,γ$16$]]
match expected type cats.Bifunctor[A.MyBifunctor] [25:21]
And unfortunately both:
- catsDataBifunctorForEitherT
- catsDataBitraverseForEitherT
are private so I can't provide one explicitly.
I found that issue trying to understand why I could do a leftWiden on :
EitherT[IO, ?, ?] and not on EitherT[Option, ?, ?]
are private so I can't provide one explicitly.
Actually they are both public. Implicits have to be public to work at all. How did you try using them, what is the compiler error?
EitherT[IO, ?, ?]
See also a discussion here about why you should not use EitherT
and other monad transformers with IO
.
Yes, there is a conflict indeed among implicits. The problem is that there are both catsDataBifunctorForEitherT
and catsDataBitraverseForEitherT
implicits available:
implicit def catsDataBifunctorForEitherT[F[_]](implicit F: Functor[F]): Bifunctor[EitherT[F, *, *]]
implicit def catsDataBitraverseForEitherT[F[_]](implicit F: Traverse[F]): Bitraverse[EitherT[F, *, *]]
Consequently, the first one requires Functor
for F
whereas the second one – Traverse
.
However, there are both implementations available for Option
:
// Invariant.scala
implicit def catsInstancesForOption: MonadError[Option, Unit] with Alternative[Option] with CoflatMap[Option] with CommutativeMonad[Option]
// UnorderedFoldable.scala
implicit def catsTraverseForOption: Traverse[Option]
Therefore, Scala cannot choose which one to pick up.
And it is not just for Option
, e.g. List
has the same issue:
val bifunET = Bifunctor[EitherT[List, *, *]]
ambiguous implicit values:
both method catsDataBitraverseForEitherT in class EitherTInstances1 of type [F[_]](implicit F: cats.Traverse[F]): cats.Bitraverse[[β$69$, γ$70$]cats.data.EitherT[F,β$69$,γ$70$]]
and method catsDataBifunctorForEitherT in class EitherTInstances of type [F[_]](implicit F: cats.Functor[F]): cats.Bifunctor[[β$15$, γ$16$]cats.data.EitherT[F,β$15$,γ$16$]]
match expected type cats.Bifunctor[[β$2$, γ$3$]cats.data.EitherT[[+A]List[A],β$2$,γ$3$]]
val bifunET = Bifunctor[EitherT[List, *, *]]
☝️ This is for Scala 2.13.13.
The issue is that the priorities are swapped. Bitraverse
is a subtype of Bifunctor
but catsDataBitraverseForEitherT
is defined in a supertype of catsDataBifunctorForEitherT
. You can move catsDataBitraverseForEitherT
to EitherTInstances
to fix that.
are private so I can't provide one explicitly.
Actually they are both public. Implicits have to be public to work at all. How did you try using them, what is the compiler error?
Sorry you right I was tricked because there were defined in a abstract package private class that is later extended by EitherT.
One can import:
import EitherT.catsDataBifunctorForEitherT