Dmi*_*tov 2 scala covariance union-types
我有一个带有 2 个类型参数的案例类
case class Relation[T <: Model, RT] (model: T)
Run Code Online (Sandbox Code Playgroud)
类型 T 显然是一种类属性“模型”。类型 RT 可以与 T 相同,也可以是 List[T](取决于我们创建 OneToOne 或 OneToMany 的关系类型)。那么我如何限制 RT,它不允许传递除 T 或 List[T] 之外的其他内容。
PS 我正在阅读有关covariance和contravariance 的内容,但不太了解。它适用于我的情况吗?如果是,请您举例说明。如果没有 - 那么请展示其他工具来达到它。我什至无法理解 T 和 List[T] 是如何相互关联的?T <: List[T] 或 List[T] <: T?
提前致谢
在 Scala 3 中,您可以使用具有广义约束的联合类型
case class Relation[T <: Model, RT](model: T)(using (RT =:= T) | (RT =:= List[T]))
Run Code Online (Sandbox Code Playgroud)
例如
scala> class Model
| case class Relation[T <: Model, RT](model: T)(using (RT =:= T) | (RT =:= List[T]))
// defined class Model
// defined case class Relation
scala> val v = new Model
val v: Model = Model@51c26394
scala> Relation(v)
val res15: Relation[Model, Model] = Relation(rs$line$29$Model@51c26394)
scala> Relation[Model, List[Model]](v)
val res16: Relation[Model, List[Model]] = Relation(rs$line$29$Model@51c26394)
scala> Relation[Model, 42](v)
1 |Relation[Model, 42](v)
| ^
|no implicit argument of type (42 : Int) =:= Model | (42 : Int) =:= List[Model] was found for parameter x$2 of method apply in object Relation
Run Code Online (Sandbox Code Playgroud)
Thinking about T <: List[T], List[T] <: T and covariance you're trying to solve your problem using OOP/subtype polymorphism.
In Scala 2 you can try a type class (ad hoc polymorphism)
case class Relation[T <: Model, RT](model: T)(implicit sel: Selector[T, RT])
trait Selector[T <: Model, RT]
object Selector {
implicit def single[T <: Model]: Selector[T, T] = null
implicit def multiple[T <: Model]: Selector[T, List[T]] = null
}
Run Code Online (Sandbox Code Playgroud)
How to define "type disjunction" (union types)?
| 归档时间: |
|
| 查看次数: |
72 次 |
| 最近记录: |