我的方法和 Predef 中的一致性之间存在隐含歧义的问题

发布于 2024-10-24 23:22:04 字数 1611 浏览 3 评论 0原文

以下代码,摘自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)

  }
}

The following code, which is taken from Apocalisp's excellent blog series:
Type level programming in scala , and modified for an implicit parsing scenario. However, this does not compile, with the following message:

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)

Can someone please explain why this happens, and if it's fixable?

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)

  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰ゝ天使的微笑 2024-10-31 23:22:04

虽然我无法准确告诉您 Predef.conforms 的目的,但我可以告诉您歧义错误似乎是正确的(不幸的是)。在源代码的评论中,它甚至说 <:< 是由于 Function1 的歧义问题而引入的(说 Function2 但我猜这是一个错误)。但由于 <:<Function1 的子类,因此只要需要 Function1 就可以传入它,因此在您的情况下可以将 <:< 传递给 hparse。

现在隐式 def 符合 [A]: A <:< A 的效果(根据我的理解),每当一个方法需要类型 A =>; A,作用域内有一个隐式值 A 就足够了。

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

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

  • 只需删除 hParseNil,我认为您的代码仍然有效。
  • 通过命名相同的名称来隐藏 Predefconforms

    隐式 def 符合:HNil => HNil=_=> new HNil

Although i can't tell you exactly the purpose of Predef.conforms, i can tell you the ambiguity error seems correct (unfortunately). In the comment in the source it even says that <:< was introduced because of ambiguity problems of Function1 (says Function2 but i guess that is a mistake). But since <:< is a subclass of Function1 it can be passed in whenever Function1 is expected, so in your case its possible to pass in <:< to hparse.

Now the implicit def conforms[A]: A <:< A has the effect (from what i understand) that whenever a method expects a type A => A, it is sufficient to have an implicit value of A in scope.

In your case the implicit def hParseNil: HNil => HNil has the same priority as conforms and thus both could be equally applied.

I see two possible solutions:

  • just remove the hParseNil, i think your code still works.
  • shadow the Predef's conforms by naming yours the same:

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

感情旳空白 2024-10-31 23:22:04

您只需将函数文字 hParseNil 替换为普通函数即可。

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

而不是

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

You can just replace the function literal hParseNil to a normal function.

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

instead of

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文