How to use the name as an application?

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 Monad , therefore an Applicative too. Why is this code not working? Do I need to add type annotations for them to work? Thanks!

+4
source share
1 answer

Just a partial answer, I'm not too familiar with the tale. (a |@| b) is ApplicativeBuilder[Name, Int, Int] . Your call to apply(plus: (Int, Int) => Int) requires two implicit parameters: a Functor[Name] and Apply[Name] (a little smaller than Applicative , no clean).

There is a problem with the second. Because Name appears in the type of Apply[Name] , the companion object Name considered for the implicit region, and therefore the implicit val nameMonad: Monad[Name] is in the implicit region. Because Monad extends Applicative , which extends Apply , this is a possible candidate for an implicit parameter.

But since Apply appears in Apply[Name] , its companion Apply object, the companion object Apply is also considered. And his ancestor ApplyLow has

 implicit def FunctorBindApply[Z[_]](implicit t: Functor[Z], b: Bind[Z]): Apply[Z] 

Functor[Name] and Bind[Name] instances are present in the implicit scope (nameMonad is both of them), so FunctorBindApply also provides an Apply candidate (which will behave exactly like nameMonad, since it is completely based on it, but this is another candidate).

I don’t think I really understand the rules of priority. A definition in ApplyLow rather than Apply will reduce priority over what is defined in the companion Apply object. But not regarding anything specific in an unrelated Name object. I don’t think that Monad is a subtype of Apply considers it more specific. And I do not see another rule that could decide between them, but I must admit that I lost a little there. Compiler error messages certainly agree that it can choose between alternatives.

Not sure what the right solution should be, but the presence of nameMonad directly in scope, for example, with import Name._ should give it priority.

+9
source

All Articles