import scalaz._; import Scalaz._
def foo[M[_]:MonadPlus,A](a:A) = a.point[M]
// foo: [M[_], A](a: A)(implicit evidence$1: scalaz.MonadPlus[M])M[A]
def bar1[M[_]:MonadPlus](i:Int): M[Int] =
foo(i) // <-- error: ambiguous implicit values
// this works, but why? Isn't it just the same?
def bar2[M[_]:MonadPlus](i:Int): M[Int] =
foo(i)(implicitly[MonadPlus[M]])
def bar3[M[_]](i:Int)(implicit m:MonadPlus[M]): M[Int] =
foo(i)(m) // slightly less surprising that this works
def bar4[M[_]:MonadPlus](i:Int): M[Int] =
foo[M,Int](i) // this also works, but why?
build.sbt:
scalaVersion := "2.9.2"
libraryDependencies += "org.scalaz" %% "scalaz-core" % "7.0.0-M5"
(虽然我在2.10.0-RC3中得到了相同的结果)
答案 0 :(得分:2)
如果您只是写下来,则会收到相同的错误消息:
import scalaz._; import Scalaz._
def foo[M[_]:MonadPlus,A](a:A) = a.point[M]
foo(1) // <-- error: ambiguous implicit values
// both value listInstance ...
// and value optionInstance ...
我的理解是编译器试图对bar1
方法的“主体”进行类型检查,而不考虑范围内可能存在MonadPlus[M]
实例(由bar
定义引入),它已找到2个适用于MonadPlus[M]
调用的特定foo
实例(listInstance和optionInstance)。在这个阶段,它只是宣布一种模糊性。
然后在bar2
和bar3
中明确指定要使用的实例,并在bar4
中提供M
和Int
的类型参数foo
调用没有含糊不清,因为这些约束中唯一隐含的范围是implicitly[MonadPlus[M]]
。