4
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でも同じ結果が得られますが)

4

1 に答える 1

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が存在する可能性があることを考慮せずに(定義によってもたらされる)、適切な2つの特定のインスタンス(listInstanceとoptionInstance)をすでに検出しています。呼び出し。この段階では、あいまいさを宣言するだけです。MonadPlus[M]barMonadPlus[M]foo

次に、でbar2使用bar3するインスタンスを明示的に指定し、これらの制約を持つスコープ内の暗黙的なものはであるため、呼び出しであいまいではないbar4型パラメーターを指定します。MIntfooimplicitly[MonadPlus[M]]

于 2012-12-04T00:05:16.847 に答える