2011-09-16 4 views
4
scala> val a = Need(20) 
a: scalaz.Name[Int] = [email protected] 

scala> val b = Need(3) 
b: scalaz.Name[Int] = [email protected] 

scala> for(a0 <- a; b0 <- b) yield a0 + b0 
res90: scalaz.Name[Int] = [email protected] 

scala> (a |@| b) 
res91: scalaz.ApplicativeBuilder[scalaz.Name,Int,Int] = scalaz.ApplicativeBuilde 
[email protected] 

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) { _ + _ } 
       ^

NameMonadであり、従ってApplicativeである。なぜこのコードは動作しませんか?それを動作させるには、どのような型の注釈を付ける必要がありますか?ありがとう!申請者として名前を使用するにはどうすればよいですか?

答えて

9

私はスカラズにあまり精通していません。 (a |@| b)ApplicativeBuilder[Name, Int, Int]です。 apply(plus: (Int, Int) => Int)への電話には、Functor[Name]Apply[Name]の2つの暗黙的なパラメータが必要です(少ししかApplicative未満、純粋ではありません)。

2番目の問題に問題があります。 NameはタイプApply[Name]と表示されているため、コンパニオンobject Nameは暗黙のスコープと見なされるため暗黙的なval nameMonad: Monad[Name]は暗黙のスコープに含まれています。 Monadは、Applyを拡張するApplicativeまで拡張されているため、暗黙的なパラメータの候補になります。

しかし、Applyは、Apply[Name]のコンパニオンオブジェクトApplyにあり、コンパニオンobject Applyも考慮されます。そして、その祖先ApplyLowで、Functor[Name]Bind[Name]

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

インスタンス(nameMonadは、それらの両方である)暗黙のスコープ内に存在しているされているので、FunctorBindApplyはそれとしてnameMonadとして正確に振る舞うことになる(あまりにも候補Applyを提供しますそれに完全に基づいていますが、それにもかかわらず、もう一つの候補者です)。

私は本当に優先ルールを理解しているとは思わない。 ApplyではなくApplyLowの定義を持つと、コンパニオンオブジェクトApplyで定義されているものに比べて優先度が低くなります。しかし、関連のないオブジェクトNameに定義されたものとは関係ありません。より具体的には、Applyのサブタイプであると考えていません。そして私は2つの間で決めることができる他の規則を見ないが、私はそこに紛失していると少し告白しなければならない。コンパイラのエラーメッセージは確かにそれが選択肢の中から選択できることに同意します。

わからない適切なソリューションがどうあるべきか、しかしimport Name._で、たとえば、直接スコープでnameMonadを持つことは、それに優先順位を与える必要があります。

+0

それを修正しました。ありがとう! – missingfaktor

+4

暗黙的なスコープに頼っている場合、適切な暗黙の優先順位を与えるための合理的な解決策は見つかりませんでした。型クラスインスタンスを明示的にインポートすることは、時には唯一の方法です。この問題を避けるため、Scalaz7(http://code.google.com/p/scalaz/wiki/Scalaz7)の新しいデザインが試作されています。 – retronym