У меня есть эти две черты:
sealed trait DbValue {
type R
type T <: DbValue
def content(): R
def copy(newContent: R = content): Option[T]
def toString(): String
}
sealed trait DbValueOps {
type R
type T <: DbValue
def apply(newContent: R): Option[T]
def fromString(newContent: String): Option[T]
def isValidContent(newContent: R): Boolean
}
и хотите создать метод/класс, который принимает объекты, реализующие обе черты, однако DbValue реализуется классом, а DbValueOps реализуется сопутствующим объектом.
Пример:
case class Column[T <: DbValue with DbValueOps] (val name: String, val cells: Vector[Option[T]] = Vector(), val blank_allowed: Boolean = true) {}
Теперь я хочу создать общий столбец для типа, который реализован следующим образом:
case class DbString private (val content: String) extends DbValue {
type R = String
type T = DbString
def copy(newContent: String = content): Option[DbString] = DbString(newContent)
override def toString(): String = content
}
object DbString extends DbValueOps {
type R = String
type T = DbString
def apply(newContent: String): Option[DbString] =
isValidContent(newContent) match {
case true => Some(new DbString(newContent))
case false => None
}
def fromString(newContent: String): Option[DbString] = DbString(newContent)
def isValidContent(newContent: String): Boolean = !newContent.isEmpty
}
Однако, когда я пытаюсь создать такой столбец с: Column[DbString]("name")
, я получаю сообщение об ошибке: type arguments [database.DbString] do not conform to method apply's type parameter bounds [T <: database.DbValue with database.DbValueOps]
Есть ли хороший способ сделать это? Или как мне изменить свой дизайн?