Reputation: 956
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"
(although I get the same result in 2.10.0-RC3)
Upvotes: 4
Views: 210
Reputation: 15557
You get the same error message if you simply write:
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 ...
My understanding is that the compiler tries to typecheck the "body" of the bar1
method and without considering that there may be a MonadPlus[M]
instance in scope (brought by the bar
definition), it already finds 2 specific MonadPlus[M]
instances (listInstance and optionInstance) which are suitable for a foo
invocation. At this stage it just declares an ambiguity.
Then in bar2
and bar3
you specify explicitly the instance to use and in bar4
you give the type parameters which are M
and Int
which is not ambiguous on the foo
call because the only implicit in scope with these constraints is implicitly[MonadPlus[M]]
.
Upvotes: 2