以下代码摘自Apocalisp的出色博客系列:
Type level programming in 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)

  }
}

最佳答案

尽管我无法确切告诉您Predef.conforms的目的,但我可以告诉您歧义错误似乎是正确的(不幸的是)。在源代码中的注释中,它甚至说引入<:<是因为Function1的歧义性问题(说Function2,但我想那是一个错误)。但是由于<:<Function1的子类,因此可以在需要Function1时将其传递,因此在您的情况下,可以将<:<传递给hparse。

现在implicit def conforms[A]: A <:< A具有效果(据我了解),只要方法期望类型为A => A,就在作用域中具有隐含的A值就足够了。

在您的情况下,implicit def hParseNil: HNil => HNil具有与conforms相同的优先级,因此两者可以同等适用。

我看到两种可能的解决方案:

  • 只需删除hParseNil,我认为您的代码仍然有效。
  • 用相同的名称来遮盖Predefconforms:
    implicit def conforms: HNil => HNil = _ => new HNil
  • 关于scala - 我的方法与在Predef中一致之间存在隐含歧义的问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5377492/

    10-12 01:27