为什么我似乎无法正确地将无形记录与选项合并?

时间:2016-08-15 21:23:03

标签: scala shapeless

如果我按如下方式合并两条记录:

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") :: HNilc.keysKey :: Key :: HNil。是什么给了什么?

如果这有任何不同,我正在使用Shapeless 2.1。

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的工作原理:

  1. 我们可以看到优先级最高的implicithttps://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/records.scala#L179-L191)更喜欢记录之间的值类型匹配。它替换合并记录输出中的值。
  2. 优先级较低implicithttps://github.com/milessabin/shapeless/blob/master/core/src/main/scala/shapeless/ops/records.scala#L162-L167) 仅当类型不匹配,附加头部和时,才会激活 然后迭代地遍历记录的结构。
  3. 最后,在HNil的情况下,它只是将第二个记录中所有其他操作之后的剩余内容附加到第一个记录中。也就是说,如果它们的大小不匹配,则需要其他任何可用的东西。