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

mis*_*tor 4 monads functional-programming scala 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) { _ + _ }
                 ^
Run Code Online (Sandbox Code Playgroud)

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

Did*_*ont 9

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

第二个有问题.如Name类型中所示Apply[Name],companion object Name被认为是隐式作用域,因此隐式val nameMonad: Monad[Name]作用在隐式作用域中.作为Monad扩展的Applicative扩展Apply,它是隐含参数的可能候选者.

但正如其伴侣对象ApplyApply[Name]所见Apply,同伴object Apply也被考虑在内.在它的祖先ApplyLow,有一个

implicit def FunctorBindApply[Z[_]](implicit t: Functor[Z], b: Bind[Z]): Apply[Z] 
Run Code Online (Sandbox Code Playgroud)

隐式范围中存在Functor[Name]Bind[Name]存在的实例(nameMonad都是它们),因此也FunctorBindApply提供了候选者Apply(其行为与nameMonad完全相同,因为它完全基于它,但它仍然是另一个候选者).

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

不确定正确的解决方案应该是什么,但是nameMonad直接在范围内,例如,import Name._ 应该优先考虑.

  • 在依赖隐式范围时,我们还没有找到合理的解决方案来为我们提供正确的隐含优先级.有时显式导入类型类实例是唯一的方法.新设计正在为Scalaz7(http://code.google.com/p/scalaz/wiki/Scalaz7)制作原型,以避免此问题. (4认同)