проблема с неявной неоднозначностью между моим методом и соответствует в Predef - PullRequest
2 голосов
/ 21 марта 2011

Следующий код, который взят из отличной серии блогов 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 ]

5 голосов
/ 21 марта 2011

Хотя я не могу сказать вам точно цель Predef.conforms, я могу сказать, что ошибка неоднозначности кажется правильной (к сожалению). В комментарии в источнике даже говорится, что <:< было введено из-за проблем с неопределенностью Function1 (говорит Function2, но я думаю, что это ошибка). Но поскольку <:< является подклассом Function1, его можно передавать всякий раз, когда ожидается Function1, поэтому в вашем случае можно передать <:< в hparse.

Теперь implicit def conforms[A]: A <:< A имеет эффект (насколько я понимаю), что всякий раз, когда метод ожидает тип A => A, достаточно иметь неявное значение A в области видимости.

В вашем случае implicit def hParseNil: HNil => HNil имеет тот же приоритет, что и conforms, и поэтому оба могут применяться одинаково.

Я вижу два возможных решения:

  • просто удалите hParseNil, я думаю, ваш код все еще работает.
  • замаскируйте Predef conforms, назвав вашу же:

    implicit def conforms: HNil => HNil = _ => new HNil

1 голос
/ 23 октября 2018

Вы можете просто заменить литерал функции hParseNil на обычную функцию.

implicit def hParseNil(a:HNil): HNil = HNil

вместо

implicit def hParseNil: HNil => HNil = _ => HNil

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...