我有一种情况,我想抽象一些,并在一个或多个“原始”类型(A
及B
以下)之间建立类型协议,一个应该返回Seq(Option[A], Option[B], ...)
这些类型对应的方法(如下命名extract
),以及一组字段配置(命名configs
如下),每个都知道如何获取相应“原始”类型的值。
在下面的代码中,理想情况下我想要Dimensions1
并且Dimension2
不存在。如果我必须做某种类似s.c.i.List
递归的头/尾构造,我会同意的。:)
/***
scalaVersion := "2.11.4"
libraryDependencies := Seq("com.chuusai" %% "shapeless" % "2.0.0")
*/
object Main extends App {
import shapeless._
case class JsonEventRecord()
case class DimensionConfig[T](name: String,
valueSource: JsonEventRecord => Option[T]) {
def extract(rec: JsonEventRecord): Option[T] = {
valueSource(rec)
}
}
trait Dimensions {
type All <: HList // I'd like to constrain this to (Option[A], Option[B], ...)
type Configs <: HList // I'd like to constrain this to (DimensionConfig[A], DimensionConfig[B], ...)
def configs: Configs
def extractAll(rec: JsonEventRecord): All
}
// I'd like this to not exist :)
trait Dimensions1 extends Dimensions {
type A
type All = Option[A] :: HNil
type Configs = DimensionConfig[A] :: HNil
val config1: DimensionConfig[A]
def configs = config1 :: HNil
override def extractAll(rec: JsonEventRecord): All = HList(config1.extract(rec))
}
// I'd like this to not exist :)
trait Dimensions2 extends Dimensions {
type A
type B
type All = Option[A] :: Option[B] :: HNil
type Configs = DimensionConfig[A] :: DimensionConfig[B] :: HNil
val config1: DimensionConfig[A]
val config2: DimensionConfig[B]
def configs = config1 :: config2 :: HNil
override def extractAll(rec: JsonEventRecord): All = {
HList(
config1.extract(rec),
config2.extract(rec)
)
}
}
}