I am trying to have a generic type definition that can be satisfied by slicks TableQuery type:
class OrderTable(tag: Tag) extends Table[Order](tag, "orders")
...
val orders = TableQuery[OrderTable]
type Ta[X] = TableQuery[Table[X]]
val orderTable: Ta[Order] = orders
What I want to achieve is that I have an abstract type definition in a trait that can be slick table but also something else like just a hashmap. I am getting the following compilation error:
found : slick.jdbc.PostgresProfile.api.TableQuery[at.gepro.dbtemplate.OrderTable]
(which expands to) slick.lifted.TableQuery[at.gepro.dbtemplate.OrderTable]
required: SlickOrderRepository.this.Ta[at.gepro.dbtemplate.Order]
(which expands to) slick.lifted.TableQuery[slick.jdbc.PostgresProfile.Table[at.gepro.dbtemplate.Order]]
I don't understand why this assignment does not work, everything uses the PostgresProfile
api.
tried AbstractTable
but did not work either
Because TableQuery
is invariant
class TableQuery[E <: AbstractTable[?]](cons: Tag => E) extends Query[E, E#TableElementType, Seq]
https://github.com/slick/slick/blob/v3.5.0-M2/slick/src/main/scala/slick/lifted/Query.scala#L322
It's not covariant TableQuery[+E <: AbstractTable[?]]
.
OrderTable
is a subtype of Table[Order]
but TableQuery[OrderTable]
is not a subtype of TableQuery[Table[Order]]
implicitly[OrderTable <:< Table[Order]] // compiles
// implicitly[TableQuery[OrderTable] <:< TableQuery[Table[Order]]] // doesn't compile
Try:
type Ta[X] = TableQuery[? <: Table[X]]
// type Ta[X] = TableQuery[_ <: Table[X]] // former syntax
val orderTable: Ta[Order] = orders
https://stackoverflow.com/questions/tagged/existential-type%2bscala?tab=Votes
type Ta[X, T <: Table[X]] = TableQuery[T]
val orderTable: Ta[Order, OrderTable] = orders
You can read about variances in Scala: