如果我按如下方式合并两条记录:
case object Key
val a = (Key ->> Option.empty[String]) :: HNil
val b = (Key ->> Option("plif")) :: HNil
val c = a.merge(b)
然后我们希望我们有b == c
。但是,如果我为None
使用普通字符串而不是a
,则不再适用:
case object Key
val a = (Key ->> "pluf") :: HNil
val b = (Key ->> Option("plif")) :: HNil
val c = a.merge(b)
在这种情况下,c
原来是:"pluf" :: Some("plif") :: HNil
而c.keys
是Key :: Key :: HNil
。是什么给了什么?
如果这有任何不同,我正在使用Shapeless 2.1。
答案 0 :(得分:4)
我认为合并的类型必须与合并一致。也就是说,它们必须属于同一类型。在第一种情况下,您有2 Option[String]
种类型,而在第二种情况下,您有Option[String]
和String
。
查看代码(https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/records.scala#L157-L192)并通过隐式逻辑来理解Merger
的工作原理:
implicit
(https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/records.scala#L179-L191)更喜欢记录之间的值类型匹配。它替换合并记录输出中的值。 implicit
(https://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/records.scala#L162-L167)
仅当类型不匹配,附加头部和时,才会激活
然后迭代地遍历记录的结构。HNil
的情况下,它只是将第二个记录中所有其他操作之后的剩余内容附加到第一个记录中。也就是说,如果它们的大小不匹配,则需要其他任何可用的东西。