4
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:当我删除类型注释时,代码编译得很好。

4

2 回答 2

7

这里的根本问题是从未推断出单例类型。这是一个演示:

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

为什么是这样?Quoth Odersky 等。人。在 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)

奖励链接:

于 2010-10-11T20:20:56.933 回答
2

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

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

object HNil extends HNilClass
于 2010-10-11T16:01:14.440 回答