如何正确地对该 HList 进行类型注释?

发布于 2024-09-27 03:38:18 字数 787 浏览 3 评论 0原文

sealed abstract trait HList

case class :+:[H, T <: HList](head: H, tail: T) extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

case object HNil extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

object HListExpt {
  def main(args: Array[String]) {
    val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil
    println(me.head, me.tail.head)
  }
}

在尝试编译上述代码时,我收到以下编译器错误:

error: type mismatch;
found   : :+:[java.lang.String,:+:[Int,:+:[Symbol,object HNil]]]
required: :+:[String,:+:[Int,:+:[Symbol,HNil.type]]]
val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil

我在这里做错了什么?对上述 HList 进行类型注释的正确方法是什么?

PS:当我删除类型注释时,代码可以正常编译。

sealed abstract trait HList

case class :+:[H, T <: HList](head: H, tail: T) extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

case object HNil extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

object HListExpt {
  def main(args: Array[String]) {
    val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil
    println(me.head, me.tail.head)
  }
}

On trying to compile the above code, I get the following compiler error:

error: type mismatch;
found   : :+:[java.lang.String,:+:[Int,:+:[Symbol,object HNil]]]
required: :+:[String,:+:[Int,:+:[Symbol,HNil.type]]]
val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil

What am I doing wrong here? What would be the correct way to type-annotate the above HList?

PS: The code compiles fine when I remove the type annotation.

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

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

发布评论

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

评论(2

七堇年 2024-10-04 03:38:18

这里的根本问题是单例类型永远不会被推断。这是一个演示:

scala> case object A      
defined module A

scala> A                  
res6: A.type = A

scala> identity[A.type](A)
res7: A.type = A

scala> identity(A)        
res8: object A = A

这是为什么?奥德斯基等人。等人。 Scala 编程,§27.6:

通常 [singleton] 类型也是如此
具体有用,这就是为什么
编译器不愿意插入
它们会自动出现。

因此,让我们明确提供类型参数:

sealed abstract trait HList

case class :+:[H, T <: HList](head: H, tail: T) extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

case object HNil extends HList {
  def :+:[T](v: T) = new :+:[T, HNil.type](v, this)
}

val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil
println(me.head, me.tail.head)

额外链接:

The root problem here is that singleton types are never inferred. Here's a demonstration:

scala> case object A      
defined module A

scala> A                  
res6: A.type = A

scala> identity[A.type](A)
res7: A.type = A

scala> identity(A)        
res8: object A = A

Why is this? Quoth Odersky et. al. in Programming in Scala, §27.6:

Usually [singleton] types are too
specific to be useful, which is why
the compiler is reluctant to insert
them automatically.

So, let's explicitly provide the type argument:

sealed abstract trait HList

case class :+:[H, T <: HList](head: H, tail: T) extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

case object HNil extends HList {
  def :+:[T](v: T) = new :+:[T, HNil.type](v, this)
}

val me: String :+: Int :+: Symbol :+: HNil.type = "Rahul" :+: 20 :+: 'Male :+: HNil
println(me.head, me.tail.head)

Bonus Link:

心房的律动 2024-10-04 03:38:18

我不知道为什么,但如果 HNil 被定义为一个类,那么一切都会编译:

class HNilClass extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

object HNil extends HNilClass

I'm not sure why, but if HNil is defined as a class everything compiles:

class HNilClass extends HList {
  def :+:[T](v: T) = new :+:(v, this)
}

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