scalagenericsscala-3existential-typehigher-kinded-types

How to do the equivalent of T[Any] for higher kinded types in scala


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?

Solution

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