证明泛型类型的上限类型

时间:2017-10-02 19:34:15

标签: scala generics types

我有一个类型类,我想用它来存储一种对象:

trait RetainType {
  type A
}

object RetainType {
  def apply[A0](): RetainType = new RetainType{
    type A = A0
  }
}

鉴于以下课程:

trait Annotation
class Entity extends Annotation

我希望编译器证明RetainType.A扩展Annotation

def hasAnnotation[A <: Annotation] = Unit

但是使用RetainType编译器似乎无法解决这个问题:

val retainType = RetainType[Entity]
hasAnnotation[RetainType.A] //throws an error: type arguments [retainType.A] do not conform to method hasAnnotation's type parameter bounds [A <: Annotation]

如果指定了类型,它就可以了:

hasAnnotation[Entity] //works fine

无论如何编译器可以证明这种关系吗?

1 个答案:

答案 0 :(得分:5)

你搞砸了RetainType.apply的签名:

def apply[A0](): RetainType

返回类型未提及A0,因此它已被遗忘&#34;。也就是说,

val x = RetainType[Int]

x.A完全是抽象的;编译器无法证明x.A = Int,因为apply的签名会删除该信息。使用细化类型:

object RetainType {
  def apply[A0](): RetainType { type A = A0 } = new RetainType { override type A = A0 }
}

您可能希望使用Aux模式来更好地使用:

object RetainType {
  type Aux[A0] = RetainType { type A = A0 }
  def apply[A0](): RetainType.Aux[A0] = new RetainType { override type A = A0 }
}