В попытке ответить на this question, я придумал следующий код:разрешение Scala нескольких неявных параметров
case class Monkey(bananas: Int)
case class Tree(rings: Int)
case class Duck(quacks: Seq[String])
implicit class IntLike(val x : Int) extends AnyVal
implicit def monkey2Age(monkey: Monkey): IntLike = monkey.bananas/1000
implicit def tree2Age(tree: Tree): IntLike = tree.rings
implicit def duck2Age(duck: Duck): IntLike = duck.quacks.size/100000
def purchaseCandles[A <% IntLike]()(implicit age : A) = {
val asAge : IntLike = age
println(s"I'm going to buy $asAge candles!")
}
{
implicit val guest = Tree(50)
purchaseCandles()
}
Обратите внимание, что IntLike
только там, чтобы убедить меня, что это не проблема, сфокусированы на Int
.
Это кажется довольно стандартным, если плохо, использование implicits, и я ожидал, что он будет работать с удовольствием. Однако, ссылаясь на purchaseCandles()
РЕПЛ дает следующее сообщение об ошибке:
error: ambiguous implicit values: both value StringCanBuildFrom in object Predef of type => scala.collection.generic.CanBuildFrom[String,Char,String] and value guest of type Tree match expected type A
Я не могу за жизнь мне увидеть, как это бывает. A обязана иметь вид вида IntLike
, тип, который я только что придумал. РЕПЛИ подтверждает, что не существует никакого неявного вида в наличии:
scala> implicitly[Tree => IntLike]
res14: Tree => IntLike = function1
но
scala> implicitly[scala.collection.generic.CanBuildFrom[String, Char, String] => IntLike]
:18: error: No implicit view available from scala.collection.generic.CanBuildFrom[String,Char,String] => IntLike.
Так как может быть StringCanBuildFrom
соответствующего типа? Является ли компилятор способным разрешать множественные зависимые импликации, а если нет, то почему это ошибка отображается?
Да , что выходит за рамки неявного разрешения, кажется вероятным, но сообщение запутывает. Все работает, если вы явно указываете параметр типа: 'test [Foo.type]' в вашем примере. – Impredicative