2010-10-11 3 views
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) 
    } 
} 

En essayant de compiler le code ci-dessus, je reçois l'erreur du compilateur suivant:Comment correctement annoter ce HList?

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 

ce que je fais mal ici? Quelle serait la bonne façon de taper-annoter le HList ci-dessus? PS: Le code compile bien lorsque je supprime l'annotation de type.

Répondre

7

Le problème racine est ici que les types singletons ne sont jamais inférées. Voici une démonstration:

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 

Pourquoi est-ce? Quoth Odersky et. Al. en programmation Scala, §27.6:

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

Donc, nous allons fournir explicitement l'argument de 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) 

Bonus lien:

2

Je ne sais pas pourquoi, mais si HNil est défini comme tout de classe compile:

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

object HNil extends HNilClass 
Questions connexes