如何定义具有未绑定类型参数的成员的案例类? [英] How to define case classes with members with unbound type parameters?

查看:214
本文介绍了如何定义具有未绑定类型参数的成员的案例类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个具有绑定类型参数 Animal [A<:String] 的类定义,似乎Scala编译器不会推断出 B< :来自动物[B] 的字符串。推论是否允许?如何帮助编译器进行推理?



下面是一个案例类的具体例子,其中缺乏这种推断是一个问题。



考虑下面的案例类层次:

 密封特质Person [+ T< Person [ T]] 
case class Student()extends Person [Student]
case class Professor()extends Person [教授]

我需要定义一个案例类 University ,我可以使用 Person [_]类型的变量来实例化。 ,例如 val p:Person [_] = Student()。我认为这可以与以下定义一起工作:

pre code> case class University(p:Person [_])

但是,这个错误编译失败:

  type arguments [Any]不符合trait Person的类型参数bounds [+ T<:Person [T]] 

如果我绑定了case类 University 的类型参数,它会编译(如果我放下 case 关键字,但这不是我的例子中的选项):

  case class BoundUniversity [P] Person [P]](p:Person [P])

但是这个参数化版本无法使用 Person [_] 的无界变量实例化:

  val p:Person [_] = Student()
BoundUniversity(p)

无法编译:

 推断的类型参数[_ $ 1]不符合m到方法apply的类型参数bounds [P<:Person [P]] 

发生同样的错误对于一个有如下绑定参数的方法:

  def general [P<:Person [P]](p:P) = println(p)

所以这不是特定于类构造函数的。



两个问题:


  1. 类型 Person 用参数范围 Person [+ T <:Person [T]] 定义,这样这个类型的每个实例都被保证遵守这些范围: val p:Person [P] 意味着 P<:Person [P] ;或者我错过了什么?我怎样才能让编译器清楚这一点,使其不会抱怨?

  2. 例如 case class University(p:Person [_])



解决方案

类型 X [_] 几乎不是您想要的。当你在一个类型上使用 _ 时,你基本上说你不在乎这个参数是什么,因为你永远不需要使用它。



无论如何,这个编译。它可能会咬你的路,存在类型是他们是棘手的东西,但... ...

pre> case class University (p:Person [t] forSome {type t<:Person [t]})


Given a class definition with bound type parameter Animal[A <: String] it seems that the Scala compiler does not infer B <: String from Animal[B]. Is the inference allowed? How to help the compiler to do the inference?

Below is a concrete example with case classes where the lack of this inference is a problem.

Consider the following case class hierarchy:

sealed trait Person[+T <: Person[T]]
case class Student() extends Person[Student]
case class Professor() extends Person[Professor]

I need to define a case class University which I can instantiate with a variable of type Person[_], for example val p: Person[_] = Student(). I thought this would work with the following definition:

case class University(p: Person[_])

But this fails compiling with the error:

type arguments [Any] do not conform to trait Person's type parameter bounds [+T <: Person[T]]

If I bind the type parameter of the case class University it compiles (it also compiles with unbounded parameters if i drop the case keyword but this is not an option in my case):

case class BoundUniversity[P <: Person[P]](p: Person[P])

But this parametrized version cannot be instantiated with an unbounded variable of type Person[_]:

val p: Person[_] = Student()
BoundUniversity(p)

fails compiling with:

inferred type arguments [_$1] do not conform to method apply's type parameter bounds [P <: Person[P]]

The same error happens for a method with a bound argument like:

def general[P <: Person[P]](p: P) = println(p)

so this is not specific to class constructors.

Two questions:

  1. The type Person is defined with parameter bounds Person[+T <: Person[T]], so that each instance of this type is insured to respect those bounds: val p: Person[P] implies that P <: Person[P]; or am I missing something? So how can I make this clear to the compiler so that it doesn't complain?

  2. How/Can I define a case class with members with unbound type parameter like case class University(p: Person[_])?

解决方案

A type X[_] is hardly ever what you want. When you use _ on a type, you are basically saying you don't care what that parameter is, because you'll never need to use it.

Anyway, this compiles. It may well bite you down the road, existential types being the tricky stuff that they are, but...

case class University(p: Person[t] forSome { type t <: Person[t] })

这篇关于如何定义具有未绑定类型参数的成员的案例类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆