context: this is using scala-3
final case class TableSchema[T[_[_]] <: Table]( /* ... */ )
// None of these work...
final case class Schema(tableSchemas: List[TableSchema[_ <: Table]])
final case class Schema(tableSchemas: List[[t[_[_]] <: Table] => TableSchema[t]])
final case class Schema(tableSchemas: List[[t[_[_]] <: Table] =>> TableSchema[t]])
final case class Schema(tableSchemas: List[TableSchema[_[_[_]] <: Table]]) // isnt even valid syntax?
I guess, correct is
final case class Schema(tableSchemas: List[TableSchema[_ <: ([_[_]] =>> Table)]])
or without extra brackets
final case class Schema(tableSchemas: List[TableSchema[_ <: [_[_]] =>> Table]])
i.e. unknown argument _
of existential type TableSchema[_]
is a subtype of the constant type Table
.
A quote from Type Lambdas - More Details / Relationship with Parameterized Type Definitions:
A parameterized abstract type
type T[X] >: L <: U
is regarded as shorthand for an unparameterized abstract type with type lambdas as bounds.
type T >: ([X] =>> L) <: ([X] =>> U)
Tested in Scala 3.1.3.