Для класса типов, где выбор экземпляра должен выполняться на основе возвращаемого типа:
case class Monoid[A](m0: A) // We only care about the zero here
implicit def s[T] : Monoid[Set[T]] = Monoid(Set.empty[T])
implicit def l[T] : Monoid[List[T]] = Monoid(List.empty[T])
def mzero[A](implicit m: Monoid[A]) : A = m.m0
почему Scala (2.11.6) не может решить соответствующий экземпляр:
scala> mzero : List[Int]
<console>:24: error: ambiguous implicit values:
both method s of type [T]=> Monoid[Set[T]]
and method l of type [T]=> Monoid[List[T]]
match expected type Monoid[A]
mzero : List[Int]
^
когда у него нет проблем с поиском неявного на основе типа возврата при использовании функции неявно (мы переопределяем его здесь как i, чтобы показать, насколько это похоже на mzero)
def i[A](implicit a : A) : A = a
scala> i : Monoid[List[Int]]
res18: Monoid[List[Int]] = Monoid(List())
Monoid[A]
, а не Monoid[List[Int]]
в сообщении об ошибке вызывает недоумение.
Я бы предположил, что многие разработчики сказанов знакомы с этой проблемой, поскольку это, по-видимому, ограничивает удобство классных классов в scala.
EDIT: Я ищу, чтобы это работало без отклонения от типа. В противном случае я бы хотел понять, почему это невозможно. Если это ограничение документировано как проблема Scala, я не смог его найти.