在我的代码库中,我使用标签将一些信息编码为类型。随着标签的使用t.asInstanceOf[T @@ U]
,我可以摆脱在包装和未包装值之间编写映射的许多麻烦。
最近我用标记类型碰壁了,因为它们破坏了我想使用的一些无形的功能,所以我正在尝试使用值类。
到目前为止,我可以使用以下方式欺骗一些带有标记类型的布尔检查:
implicit class TaggedBooleanAsFirstOperand[P1, U](val c: Rep[P1 @@ U]) {
private val em = new BooleanColumnExtensionMethods[P1](c.asInstanceOf[Rep[P1]])
type o = OptionMapperDSL.arg[Boolean, P1]
def @&&[P2, R](b: Rep[P2])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b)
def @||[P2, R](b: Rep[P2])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b)
def unary_! : Rep[P1] = em.unary_!
}
implicit class TaggedBooleanAsSecondOperand[P1](val c: Rep[P1]) {
private val em = new BooleanColumnExtensionMethods[P1](c)
type o = OptionMapperDSL.arg[Boolean, P1]
def &&@[P2, U, R](b: Rep[P2 @@ U])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b.asInstanceOf[Rep[P2]])
def ||@[P2, U, R](b: Rep[P2 @@ U])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b.asInstanceOf[Rep[P2]])
}
implicit class TaggedBooleanAsBothOperands[P1, U](val c: Rep[P1 @@ U]) {
private val em = new BooleanColumnExtensionMethods[P1](c.asInstanceOf[Rep[P1]])
type o = OptionMapperDSL.arg[Boolean, P1]
def @&&@[P2, V, R](b: Rep[P2 @@ V])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.&&[P2, R](b.asInstanceOf[Rep[P2]])
def @||@[P2, V, R](b: Rep[P2 @@ V])(implicit om: o#arg[Boolean, P2]#to[Boolean, R]): Rep[R] = em.||[P2, R](b.asInstanceOf[Rep[P2]])
}
但是,我不能简单地将AnyVal
一种类型转换为我想要的另一种类型,我必须提供一些诚实的代码来实现我想要的。
我试图阅读 Slick 源代码,但我应该从哪里开始的整个想法对我来说有点模糊 - 相关信息分布在很多地方,所以我不能简单地指出几个地方来例如弄清楚如何将一个映射Rep
到另一个或从包装和未包装的布尔值中提取数据并将它们组合起来。
一些 Slick 专家可以推荐一些好的起点吗?