Проблема с неявной неоднозначностью между моим методом и соответствует в Predef
Следующий код, взятый из превосходной серии блогов Apocalisp: Программирование на уровне типов в scala и изменение для неявного сценария синтаксического анализа. Однако это не компилируется со следующим сообщением:
error: ambiguous implicit values:
both method hParseNil in object HApplyOps of type => (com.mystuff.bigdata.commons.collections.hlist.HNil) => com.mystuff.bigdata.commons.collections.hlist.HNil
and method conforms in object Predef of type [A]<:<[A,A]
match expected type (com.mystuff.bigdata.commons.collections.hlist.HNil) => com.amadesa.bigdata.commons.collections.hlist.HNil
val l = hparse[HNil,HNil](HNil)
Может кто-нибудь объяснить, почему это происходит и можно ли это исправить?
sealed trait HList
final case class HCons[H, T <: HList](head: H, tail: T) extends HList {
def :+:[T](v: T) = HCons(v, this)
}
sealed class HNil extends HList {
def :+:[T](v: T) = HCons(v, this)
}
object HNil extends HNil
// aliases for building HList types and for pattern matching
object HList {
type :+:[H, T <: HList] = HCons[H, T]
val :+: = HCons
}
object HApplyOps
{
import HList.:+:
implicit def hParseNil: HNil => HNil = _ => HNil
implicit def hParseCons[InH,OutH,TIn <:HList,TOut<:HList](implicit parse:InH=>OutH,parseTail:TIn=>TOut): (InH :+: TIn) => (OutH :+: TOut) =
in => HCons(parse(in.head),parseTail(in.tail))
def hparse[In <: HList, Out <: HList](in:In)(implicit parse: In => Out):Out = in
}
object PG {
import HList._
def main(args: Array[String]) {
import HApplyOps._
val l = hparse[HNil,HNil](HNil)
}
}
2 ответа
Хотя я не могу сказать вам точно цель Predef.conforms
Я могу сказать, что ошибка неоднозначности кажется правильной (к сожалению). В комментарии в источнике даже сказано, что <:<
был введен из-за проблем неоднозначности Function1
(говорит Function2
но я думаю, что это ошибка). Но с тех пор <:<
это подкласс Function1
это может быть передано всякий раз, когда Function1
ожидается, поэтому в вашем случае его можно передать в <:<
разложить.
Теперь implicit def conforms[A]: A <:< A
имеет эффект (из того, что я понимаю), что всякий раз, когда метод ожидает тип A => A
достаточно иметь неявное значение A
в рамках.
В вашем случае implicit def hParseNil: HNil => HNil
имеет тот же приоритет, что и conforms
и, таким образом, оба могут быть применены в равной степени.
Я вижу два возможных решения:
- просто удалите
hParseNil
Я думаю, ваш код все еще работает. тень
Predef
"sconforms
называя ваши так же:implicit def conforms: HNil => HNil = _ => new HNil
Вы можете просто заменить функцию литерал hParseNil
к нормальной функции.
implicit def hParseNil(a:HNil): HNil = HNil
вместо
implicit def hParseNil: HNil => HNil = _ => HNil