我如何使用Name作为应用程序? [英] How do I use Name as an applicative?

查看:113
本文介绍了我如何使用Name作为应用程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 阶> 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>对于(a0 <-a; b0 <-b),产生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 | b){_ + _}
< console>:19:error:ambiguous implicit values:
这两种方法中的FunctorBindApply方法在类ApplicationLow中[Z [_]] :scala
z.Functor [Z],隐式b:scalaz.Bind [Z])scalaz.Apply [Z]
和value nameMonad in object Name of type => scalaz.Monad [scalaz.Name]
匹配预期类型scalaz.Apply [scalaz.Name]
(a | @ | b){_ + _}
^

名称 Monad ,因此也是 Applicative 。为什么这个代码不工作呢?我是否需要使用任何类型的注释来使其工作?谢谢!

解决方案

只是一个部分的答案,我不太熟悉scalaz。 (a | @ | b) ApplicativeBuilder [名称,Int,Int] 。您调用应用(加:(Int,Int)=> Int)需要两个隐式参数,a Functor [Name] 和一个 Apply [Name] (稍小于 Applicative ,没有纯粹的)。

第二个是有问题的。作为名称出现在类型应用[名称] ,伴侣对象名称被认为是隐式作用域,所以隐式 val nameMonad:Monad [Name] 处于隐式作用域中。作为 Monad 扩展 Applicative ,它扩展了 Apply ,它是一个隐式参数的可能候选者。

但在应用[名称] 中出现 Apply 其伴侣对象应用,伴侣对象应用也被考虑到。在它的祖先 ApplyLow 中,有一个

 隐式def FunctorBindApply [ Z [b]:隐式t:Functor [Z],b:Bind [Z]):应用[Z] 

<隐藏范围内存在 Functor [名称] 绑定[名称] 的实例(nameMonad is所以 FunctorBindApply 也提供了一个候选 Apply (它的行为与nameMonad完全一样,因为它完全基于在它上面,但它是另一个候选人)。

我不认为我真的理解优先权规则。定义在 ApplyLow 而不是 Apply 中会降低与配对对象中定义的相关的优先级应用。但不相对于在不相关对象名称中定义的内容。我不认为 Monad 应用计数的子类型,因为它使得它更具体。而且我看不出任何其他可以在两者之间做出决定的规则,但我必须承认我在那里有点失落。编译器错误消息当然同意它可以在各种选择之间进行选择。



不知道正确的解决方案应该是什么,但直接在中有 nameMonad ,比如 import Name ._ 应该优先考虑。

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 an Monad, therefore an Applicative too. Why doesn't this code work then? Do I need to put any type annotations to make it work? Thanks!

解决方案

Just a partial answer, I'm not too familiar with scalaz. (a |@| b) is an ApplicativeBuilder[Name, Int, Int]. Your call to apply(plus: (Int, Int) => Int) requires two implicit parameter, a Functor[Name] and an Apply[Name] (a little less than Applicative, there is no pure).

There is a problem with the second one. As Name appears in type Apply[Name], companion object Name is considered for implicit scope, and so the implicit val nameMonad: Monad[Name] is in the implicit scope. As Monad extends Applicative which extends Apply, it is a possible candidate for the implicit parameter.

But as Apply appears in Apply[Name] its companion object Apply, companion object Apply is considered too. And in its ancestor ApplyLow, there is an

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

Instances of Functor[Name] and Bind[Name] are present in implicit scope (nameMonad is both of them), so FunctorBindApply provides a candidate Apply too (which would behave exactly as nameMonad as it is completely based on it, but it is another candidate nevertheless).

I don't think I really understand the priority rules. Having definition in ApplyLow rather than Apply would reduce the priority relative to something defined in companion object Apply. But not relative to something defined in unrelated object Name. I don't think Monad being a subtype of Apply counts as making it more specific. And I see no other rule that could decide between the two, but I must confess I'm a little at loss there. The compiler error messages certainly agree it can choose between the alternatives.

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

这篇关于我如何使用Name作为应用程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆