如何使用Name作为应用程序?

时间:2011-09-16 16:11:44

标签: scala functional-programming monads scalaz applicative

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

NameMonad,因此Applicative也是{{1}}。为什么这段代码不起作用呢?我是否需要添加任何类型的注释才能使其正常工作?谢谢!

1 个答案:

答案 0 :(得分:9)

只是部分答案,我对scalaz不太熟悉。 (a |@| b)ApplicativeBuilder[Name, Int, Int]。您对apply(plus: (Int, Int) => Int)的来电需要两个隐含参数:Functor[Name]Apply[Name](略小于Applicative,没有纯粹的参数)。

第二个问题。当Name出现在Apply[Name]类型中时,会将object Name作为隐式作用域考虑,因此隐式val nameMonad: Monad[Name]位于隐式作用域中。当Monad扩展Applicative扩展Apply时,它可能是隐含参数的候选者。

但由于Apply Apply[Name]出现在Apply其伴随对象object Apply中,同时也会考虑ApplyLow。在它的祖先implicit def FunctorBindApply[Z[_]](implicit t: Functor[Z], b: Bind[Z]): Apply[Z] 中,有一个

Functor[Name]

Bind[Name]FunctorBindApply的实例存在于隐式作用域中(nameMonad都是它们),因此Apply也提供了候选ApplyLow(其行为与nameMonad因为它完全基于它,但它是另一个候选者)。

我认为我不了解优先权规则。在Apply而不是Apply中定义会降低相对于随播对象Name中定义的内容的优先级。但不相对于无关对象Monad中定义的内容。我不认为ApplynameMonad的子类型,因为它更具体。我认为没有其他规则可以在两者之间作出决定,但我必须承认我在那里有点不知所措。编译器错误消息肯定同意它可以在备选方案之间进行选择。

不确定正确的解决方案应该是什么,但是直接在范围内import Name._,例如使用{{1}}应该优先考虑。{p>