scala> val a = Need(20)
a: scalaz.Name[Int] = scalaz.Name$$anon$2@173f990
scala> val b = Need(3)
b: scalaz.Name[Int] = scalaz.Name$$anon$2@35201f
scala> for(a0 <- a; b0 <- b) yield a0 + b0
res90: scalaz.Name[Int] = scalaz.Name$$anon$2@16f7209
scala> (a |@| b)
res91: scalaz.ApplicativeBuilder[scalaz.Name,Int,Int] = scalaz.ApplicativeBuilde
r@11219ec
scala> (a |@| b) { _ + _ }
<console>:19: error: ambiguous implicit values:
both method FunctorBindApply in class ApplyLow of type [Z[_]](implicit t: scala
z.Functor[Z], implicit b: scalaz.Bind[Z])scalaz.Apply[Z]
and value nameMonad in object Name of type => scalaz.Monad[scalaz.Name]
match expected type scalaz.Apply[scalaz.Name]
(a |@| b) { _ + _ }
^
Name
is an Monad
, therefore an Applicative
too. Why doesn't this code work then? Do I need to put any type annotations to make it work? Thanks!
Just a partial answer, I'm not too familiar with scalaz. (a |@| b)
is an ApplicativeBuilder[Name, Int, Int]
. Your call to apply(plus: (Int, Int) => Int)
requires two implicit parameter, a Functor[Name]
and an Apply[Name]
(a little less than Applicative
, there is no pure).
There is a problem with the second one. As Name
appears in type Apply[Name]
, companion object Name
is considered for implicit scope, and so the implicit val nameMonad: Monad[Name]
is in the implicit scope. As Monad
extends Applicative
which extends Apply
, it is a possible candidate for the implicit parameter.
But as Apply
appears in Apply[Name]
its companion object Apply
, companion object Apply
is considered too. And in its ancestor ApplyLow
, there is an
implicit def FunctorBindApply[Z[_]](implicit t: Functor[Z], b: Bind[Z]): Apply[Z]
Instances of Functor[Name]
and Bind[Name]
are present in implicit scope (nameMonad is both of them), so FunctorBindApply
provides a candidate Apply
too (which would behave exactly as nameMonad as it is completely based on it, but it is another candidate nevertheless).
I don't think I really understand the priority rules. Having definition in ApplyLow
rather than Apply
would reduce the priority relative to something defined in companion object Apply
. But not relative to something defined in unrelated object Name
. I don't think Monad
being a subtype of Apply
counts as making it more specific. And I see no other rule that could decide between the two, but I must confess I'm a little at loss there. The compiler error messages certainly agree it can choose between the alternatives.
Not sure what the right solution should be, but having nameMonad
directly in scope, for instance with import Name._
should give it priority.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With