【发布时间】:2019-09-18 12:37:02
【问题描述】:
我有一堆案例类,它们在其他密封特征中具有相同形状的对应物(每个密封特征都用于 Akka Typed 行为中的详尽模式匹配),我想从一个版本转换为具有最少样板的下一个版本。
特征看起来像这样:
object RoutingCommands {
sealed trait Command
final case class ProtocolMsg(name: String, id: Int) extends Command
}
object ProtocolCommands {
sealed trait Command
final case class ProtocolMsg(name: String, id: Int) extends Command
}
我知道我可以像这样使用shapeless.Generic 进行转换:
val msg1 = ProtocolCommands.ProtocolMsg("foo", 1)
val msg2 = Generic[RoutingCommands.ProtocolMsg].from(
Generic[ProtocolCommands.ProtocolMsg].to(msg1)
)
但是对于每次转换都必须这样做是更多样板,而不仅仅是
手工构建案例类。理想情况下,我想要一个转换器,它可以根据编译时提供的两种类型派生上述代码,例如val msg2 = convert(msg1)
作为迈出的一步,我试图将其分解为:
def convert[A,B](a: A): B = Generic[B].from(
Generic[A].to(a)
)
但这会导致:
Error:(55, 44) could not find implicit value for parameter gen: shapeless.Generic[B]
从四处挖掘,看来我需要使用Generic.Aux 这导致我:
def convert[A, B, HL <: HList](a: A)(
implicit
genA: Generic.Aux[A, HL],
genB: Generic.Aux[B, HL]
) = genB.from(genA.to(a))
当调用时:
val msg3 = convert(msg2)
结果:
Error:(61, 57) could not find implicit value for parameter genB: shapeless.Generic.Aux[B,HL]
这是可以理解的,因为没有定义返回类型。但是,我想出了如何提示B 是什么,以便可以隐式推导出genB。
【问题讨论】:
标签: scala shapeless case-class