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

どうしてこれなの?QuothOderskyet。al。Scalaでのプログラミング、§27.6:

通常、[シングルトン]型は具体的すぎて役に立たないため、コンパイラーはそれらを自動的に挿入することを躊躇します。

それでは、type引数を明示的に指定しましょう。

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 に答える