I would like to limit type [R] with only specific tuples which are listed somewhere. My main goal is: to ensure that compiler raises an error if any other tuple rather than one of expected is passed to the following trait.
trait QV_Storable[R <: QV_Cue] {
val prefix: String
val tableName = prefix.concat(Random.alphanumeric take 8 mkString)
def Make(rows: Iterable[R.storageColumns]): String
}
Then I do expect QV_Storable
accept only tuples listed in SegmentCue
because it is subtupe of QV_Cue
. Pay attention that I pass R.storageColumns
to Make(rows: Iterable[R.storageColumns])
. Thus, I do expect a way to access parameters of class type.
trait QV_Cue{
type storageColumns <: Product
type metaColumns <: Product
}
object SegmentCue extends QV_Cue {
type storageCols = (CoreDataID, String)
type metaCols = (Int, String, Date, Int)
}
Is there anyway to limit it this way? It would not be great to subtype from Tuple1, Tuple3, etc.
You can provide a type class, which only sufficient tuples implement:
trait Ok[T] {}
// (Int, Int) is Ok
implicit val tupleIntIntOk: Ok[(Int, Int)] = new Ok[(Int, Int)] {}
// (String, _) is Ok too
implicit def tupleStringAOk[A]: Ok[(String, A)] = new Ok[(String, A)] {}
trait QV_Storable[R] {
def method(implicit rok: Ok[R]): Unit
// ...
}
In this scenario you can't call QV_Storable.method
if there aren't rok
value of the right type in the scope.
This way you can create QV_Storable with any R
, but can't actually use any without proper Ok
.
A bit different approach is to make similar trick on type-level. Yet there aren't implicit resolution:
sealed trait Ok[T] {}
case class TupleIntIntOk() extends Ok[(Int, Int)]
case class TupleStringAOk[A]() extends Ok[(String, A)]
trait QV_Storable[R, OkR <: Ok[R]] {
val prefix: String
// ...
}
// compiles
val foo = new QV_Storable[(Int, Int), TupleIntIntOk] { val prefix = "xy" }
// doesn't
val bar = new QV_Storable[(Int, String), /* nothing to put here */] { val prefix = "bar "}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.