Parameter output type + higher order types + class types = :-(

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)

+4
source share
1 answer

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 ... 

I understand that the compiler is trying to describe the "body" of the bar1 method and not assuming that an instance of MonadPlus[M] (given in the definition of bar ) can be present in the region, it already finds 2 specific instances of MonadPlus[M] (listInstance and optionInstance), which suitable for calling foo . At this point, he simply declares an ambiguity.

Then, in bar2 and bar3 you explicitly specify the instance to use, and in bar4 you specify parameters of type M and Int , which are not ambiguous when calling foo , since it is only hidden in volume with these restrictions implicitly[MonadPlus[M]] .

+2
source

All Articles