Search code examples
scalacovarianceunion-types

Type parameter bounding for T and List[T]


I have a case class with 2 type parameters

case class Relation[T <: Model, RT] (model: T) 

Type T obviously is a type of class property 'model'. Type RT can be the same as T or it can be List[T] (depends on what type of Relation we create OneToOne or OneToMany). So how can i limit RT, that it would not allow to pass something else except T or List[T].

PS I was reading about covariance and contravariance, but did not understand much. Is it appliable in my case? If yes, could you please provide an example. If not - then please show other tools to reach it. I can not even understand how T and List[T] relate to each other? T <: List[T] or List[T] <: T?

Thanks in advance


Solution

  • 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
    }
    

    How to define "type disjunction" (union types)?