4
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であるMonadため、これApplicativeもです。では、なぜこのコードが機能しないのですか?それを機能させるためにタイプアノテーションを付ける必要がありますか?ありがとう!

4

1 に答える 1

9

部分的な答えですが、私はscalazにあまり精通していません。(a |@| b)ですApplicativeBuilder[Name, Int, Int]。の呼び出しには、aとanapply(plus: (Int, Int) => Int)の2つの暗黙的なパラメーターが必要です(。より少し小さいですが、純粋なものはありません)。Functor[Name]Apply[Name]Applicative

2つ目に問題があります。Nameタイプに表示されるように、Apply[Name]コンパニオンobject Nameは暗黙のスコープと見なされるため、暗黙のスコープval nameMonad: Monad[Name]は暗黙のスコープに含まれます。MonadextendsはextendsApplicativeであるためApply、暗黙的なパラメーターの候補となる可能性があります。

ただし、コンパニオンオブジェクトにApply表示されるように、コンパニオンも考慮されます。そしてその祖先には、Apply[Name]Applyobject ApplyApplyLow

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

Functor[Name]とのインスタンスはBind[Name]暗黙のスコープに存在するため(nameMonadは両方です)、FunctorBindApply候補Applyも提供します(これは、完全にそれに基づいているため、nameMonadとまったく同じように動作しますが、それでも別の候補です)。

優先ルールをよく理解していないと思います。コンパニオンオブジェクトで定義されたものに比べて優先度を下げるのでApplyLowはなく、で定義する。ただし、無関係のオブジェクトで定義されているものとは関係ありません。サブタイプであることは、それをより具体的にするものとして数えられるとは思いません。そして、私はこの2つを決定できる他のルールは見当たりませんが、私はそこで少し途方に暮れていることを告白しなければなりません。コンパイラのエラーメッセージは、選択肢から選択できることに確かに同意しています。ApplyApplyNameMonadApply

適切なソリューションがどうあるべきかはわかりませんが、nameMonadたとえばwithを直接スコープに含めるとimport Name._ 、それが優先されます。

于 2011-09-16T17:04:55.397 に答える