鉴于此代码:
path-to-your-file
如何以通用方式派生abstract class Col[A](val name: String)
case object Name extends Col[String]("name")
case object Age extends Col[Int]("age")
val cols = Name :: Age :: HNil
type TableDef = ??? // such that `type TableDef = String :: Int :: HNil`
?我怀疑它必须是一个宏,以便它可以随意TableDef
HList
。
答案 0 :(得分:1)
您可以使用shapeless.ops.Comapped
scala> import shapeless._, ops.hlist._
import shapeless._
import ops.hlist._
scala> Comapped[Col[String] :: Col[Int] :: HNil, Col]
res0: shapeless.ops.hlist.Comapped[shapeless.::[Col[String],shapeless.::[Col[Int],shapeless.HNil]],Col]{type Out = shapeless.::[String,shapeless.::[Int,shapeless.HNil]]} = shapeless.ops.hlist$Comapped$$anon$162@69bb4bc0
scala> type TableDef = res0.Out
defined type alias TableDef
scala> val foo: TableDef = "foo" :: 23 :: HNil
foo: TableDef = foo :: 23 :: HNil
scala> val foo: TableDef = "foo" :: true :: HNil
<console>:18: error: type mismatch;
found : shapeless.::[String,shapeless.::[Boolean,shapeless.HNil]]
required: TableDef
(which expands to) shapeless.::[String,shapeless.::[Int,shapeless.HNil]]
val foo: TableDef = "foo" :: true :: HNil
^
请注意,这依赖于具有Col
作为直接外部类型构造函数的元素类型。如果您希望通过子类型来隐藏Name
和Age
等隐藏Col
的类型,那么可以通过考虑子类型的Comapped
变体来实现。