# How can I enforce invariance when contravariance is required

Hello,

I have the following simple example that is working:

``````  case class S[T](a:T)

sealed trait ParamX[-T]
final case class C[T](p: T) extends ParamX[T]
final case class P[T1,T2](p1: ParamX[T1], p2: ParamX[T2]) extends ParamX[(T1,T2)]

trait SearchX[T <: ParamX[_]] {
val search: T
}

case object A extends SearchX[P[Double,Double]] {
override val search = P(C(1.0), C(2.0))
}

def grid[T](numSamples: Int)(p: ParamX[T]) = S(1.0)

def checkTest[U <: ParamX[_]](n:Int, t: SearchX[U]): S[Double] = {
val s1 = t.search
val s2 = grid(n)(s1)
s2
}

val t1: S[Double] = checkTest(10, A)
``````

Can I change this to make it work with `sealed trait ParamX[T]`?
If not, can anyone explain why or point me to an explanation?

TIA.

You can make it work if you add an extra type parameter:

``````case class S[T](a:T)

sealed trait ParamX[T]
final case class C[T](p: T) extends ParamX[T]
final case class P[T1,T2](p1: ParamX[T1], p2: ParamX[T2]) extends ParamX[(T1,T2)]

trait SearchX[A, T <: ParamX[A]] {
val search: T
}

case object A extends SearchX[(Double, Double), P[Double,Double]] {
override val search = P(C(1.0), C(2.0))
}

def grid[T](numSamples: Int)(p: ParamX[T]) = S(1.0)

def checkTest[A, U <: ParamX[A]](n:Int, t: SearchX[A, U]): S[Double] = {
val s1 = t.search
val s2 = grid(n)(s1)
s2
}

val t1: S[Double] = checkTest(10, A)
``````

@Jasper-M Once again thank you.

One question though: I understand that “declaring” the type parameter makes it visible and therefore possible to “carry” to other types for binding. I assume that the type parameter `A` in `checkTest` will bind to the `T` in `grid`. If so, is their any fundamental reason why we have to make this explicit? After all type `U` has not changed.

TIA

I’m not entirely sure what’s wrong here. Existential types make my head hurt. But I think this is some type inference limitation of the scalac compiler. Dotty seems to be able to compile it as is.

In my case its “heart burn” . But it is very nice to know Dotty swallows that without a problem (wonder how hard it is going to be to port this to Dotty).

Thank you.