вывод параметра типа + типы более высокого порядка + классы типов = :-(

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)


person arya    schedule 03.12.2012    source источник


Ответы (1)


Вы получите такое же сообщение об ошибке, если просто напишете:

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] (listInstance и optionInstance), которые подходят для вызова foo. На данном этапе он просто объявляет двусмысленность.

Затем в bar2 и bar3 вы явно указываете экземпляр для использования, а в bar4 вы задаете параметры типа, которые являются M и Int, что не является двусмысленным в вызове foo, поскольку единственным неявным в области действия с этими ограничениями является implicitly[MonadPlus[M]].

person Eric    schedule 04.12.2012
comment
Упс, да. Спустя год ответ кажется мне очевидным. bar1 не указывает, какой тип MonadPlus передать foo; bar2,bar3,bar4 либо с помощью явных аргументов, либо аргументов типа. Честно говоря, я не знаю, о чем я думал. - person arya; 28.11.2013