Просто частичный ответ, я не слишком знаком со скалазом.(a |@| b)
является ApplicativeBuilder[Name, Int, Int]
.Ваш вызов apply(plus: (Int, Int) => Int)
требует два неявных параметра: Functor[Name]
и Apply[Name]
(чуть меньше Applicative
, чистых нет).
Проблема со вторым.Поскольку Name
появляется в типе Apply[Name]
, спутник object Name
рассматривается для неявной области, и поэтому неявная val nameMonad: Monad[Name]
находится в неявной области.Поскольку Monad
расширяет Applicative
, что расширяет Apply
, это возможный кандидат для неявного параметра.
Но так как Apply
появляется в Apply[Name]
, его сопутствующий объект Apply
, считается также спутник object Apply
.И в его предке ApplyLow
есть
implicit def FunctorBindApply[Z[_]](implicit t: Functor[Z], b: Bind[Z]): Apply[Z]
Экземпляры Functor[Name]
и Bind[Name]
присутствуют в неявной области видимости (nameMonad - оба), поэтому FunctorBindApply
предоставляет кандидата Apply
тоже (который будет вести себя точно так же, как nameMonad, поскольку он полностью основан на нем, но, тем не менее, это еще один кандидат).
Не думаю, что я действительно понимаю правила приоритета.Наличие определения в ApplyLow
вместо Apply
уменьшит приоритет относительно чего-то определенного в сопутствующем объекте Apply
.Но не относительно чего-то определенного в неродственном объекте Name
.Я не думаю, что Monad
как подтип Apply
считается более конкретным.И я не вижу другого правила, которое могло бы решить между ними, но я должен признаться, что я немного растерялся.Сообщения об ошибках компилятора, безусловно, согласны с тем, что он может выбирать между альтернативами.
Не уверен, какое должно быть правильное решение, но приоритет должен иметь nameMonad
, например, с import Name._
.