无法在 HList 上进行映射

7

我试图用shapeless解决这个问题,但是由于某些原因我无法在HList上进行映射。以下是代码示例。

import shapeless._
import HList._

case class Foo(a: Option[Int], b: Option[Int])

val a = Foo(Some(3), None)

val b = Foo(Some(22), Some(1))

implicit val fooIso = HListIso(Foo.apply _, Foo.unapply _)

val mapper = new (({ type O2[+A] = (Option[A], Option[A]) })#O2 ~> Option) {
  def apply[A](x: (Option[A], Option[A])): Option[A] = x._1.orElse(x._2)
}

fooIso.fromHList(fooIso.toHList(a).zip(fooIso.toHList(b)).map(mapper))

错误信息是:
<console>:55: error: could not find implicit value for parameter mapper: shapeless.Mapper[java.lang.Object with shapeless.~>[[+A](Option[A], Option[A]),Option],shapeless.::[(Option[Int], Option[Int]),shapeless.::[(Option[Int], Option[Int]),shapeless.HNil]]]
              fooIso.fromHList(fooIso.toHList(a).zip(fooIso.toHList(b)).map(mapper))
                                                                           ^

为什么映射不起作用?
1个回答

10

有一个简单的解决方法:只需将您的函数定义为一个object而不是一个val

object f extends (({ type O2[+A] = (Option[A], Option[A]) })#O2 ~> Option) {
  def apply[A](x: (Option[A], Option[A])): Option[A] = x._1 orElse x._2
}

(请注意,我将函数命名为f而不是mapper,以避免与mapmapper隐含参数混淆。)

我不确定我能帮助解释为什么 - 在某个时候,我尝试了解为什么在Shapeless中val不能用于这种类型的操作,但我不记得我当时做到了什么程度。


9
Poly1的实现(因此~>)取决于能否在定义函数式实体时作为单例类型进行命名,这个过程平稳地进行在实体是对象且在创建稳定标识符的同时被实例化的情况下;但是在这两者被分开的情况下(通过显式的new实例化和通过val定义创建稳定标识符),情况就不那么平稳了。这有一定道理,但我无法在规范中找到合理的文本来解释...如果其他人可以,请告诉我。 - Miles Sabin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接