Ограничения типа ограничивают ограничения в старших типах при расширении признака - PullRequest
2 голосов
/ 17 апреля 2020

Давайте настроим условия выдачи

trait Bound
trait Bound2 extends Bound

trait T1[B <: Bound]
trait T2[B <: Bound2] extends T1[B]

trait WrapperT1[Tz[B2 <: Bound] <: T1[B2]]

Этот код компилируется без проблем, проблема возникает при попытке расширить WrapperT1

trait WrapperT2[Tz[B2 <: Bound2] <: T2[B2]] extends WrapperT1[T2]

// Compilator error
kinds of the type arguments (T2) do not conform to the expected kinds of the type parameters (type Tz) in trait WrapperT1.

[error] ex.T2's type parameters do not match type Tz's expected parameters:

[error] type B's bounds <: Bound2 are stricter than type B2's declared bounds <: ex.Bound

[error]     trait WrapperT2[Tz[B2 <: Bound2] <: T2[B2]] extends WrapperT1[T2]

Да B2 <: Bound2 строже, чем B2 <: Bound но я не понимаю, почему компилятор жалуется по этой причине, и я был бы рад узнать больше об этом.

Потенциальное решение, но имеет ли оно некоторые недостатки?

trait Bound
trait Bound2 extends Bound

trait T1[B] {
    implicit val ev: B <:< Bound
}

trait T2[B] extends T1[B] {
    // this is possible thank's to covariance of class `<:<[-From, +To]` if i'm not wrong
    implicit val ev: B <:< Bound2
}

trait WrapperT1[Tz[B2] <: T1[B2]]
// Compiles
trait WrapperT2[Tz[B2] <: T2[B2]] extends WrapperT1[Tz]

Это выглядит красиво, и мы сохраняем проверки компиляции о типе B2 generi c, но есть ли неудобства при его использовании?

...