代码之家  ›  专栏  ›  技术社区  ›  missingfaktor Kevin Wright

如何正确地键入注释这个列表?

  •  4
  • missingfaktor Kevin Wright  · 技术社区  · 14 年前
    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:当我删除类型注释时,代码编译得很好。

    2 回复  |  直到 14 年前
        1
  •  7
  •   retronym    14 年前

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

    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)
    

    奖金链接:

        2
  •  2
  •   Rafael de F. Ferreira    14 年前

    我不知道为什么,但如果将hnil定义为类,则所有内容都会编译:

    class HNilClass extends HList {
      def :+:[T](v: T) = new :+:(v, this)
    }
    
    object HNil extends HNilClass
    
    推荐文章