首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未在unapply中找到Scala shapeless Generic.Aux隐式参数

未在unapply中找到Scala shapeless Generic.Aux隐式参数
EN

Stack Overflow用户
提问于 2019-01-30 10:13:52
回答 2查看 256关注 0票数 1

使用Shapeless的Generic.Aux,我在Scala中遇到了下面的隐式问题

代码语言:javascript
复制
  case class Complex(re: Double, im: Double)

  object Prod2 {
    def unapply[C, A, B](c: C)(implicit C: Generic.Aux[C, A :: B :: HNil]) = Some((C.to(c).head, C.to(c).tail.head))
  }

  val c = Complex(1.0, 2.0)
  val Prod2(re, im) = c

上面的代码不能编译。它报告

代码语言:javascript
复制
Error:(22, 7) could not find implicit value for parameter C: shapeless.Generic.Aux[nexus.ops.Test.Complex,A :: B :: shapeless.HNil]
  val Prod2(re, im) = c
Error:(22, 7) not enough arguments for method unapply: (implicit C: shapeless.Generic.Aux[nexus.ops.Test.Complex,A :: B :: shapeless.HNil])Some[(A, B)].
Unspecified value parameter C.
  val Prod2(re, im) = c

但是,如果我手动执行

代码语言:javascript
复制
implicitly[Generic.Aux[Complex, Double :: Double :: HNil]]

派生这个隐式实例是完全可以的。

EN

回答 2

Stack Overflow用户

发布于 2019-01-30 16:33:03

下面的代码可以工作:

代码语言:javascript
复制
import shapeless.ops.hlist.IsHCons
import shapeless.{::, Generic, HList, HNil}

case class Complex(re: Double, im: Double)

object Prod2 {
  def unapply[C, L <: HList, H, T <: HList, H1, T1 <: HList](c: C)(implicit
    C: Generic.Aux[C, L],
    isHCons: IsHCons.Aux[L, H, T],
    isHCons1: IsHCons.Aux[T, H1, T1]) = Some((C.to(c).head, C.to(c).tail.head))
}

val c = Complex(1.0, 2.0)
val Prod2(re, im) = c
票数 1
EN

Stack Overflow用户

发布于 2019-01-30 16:34:49

不幸的是,编译器不够智能,无法执行在这里推断AB所必需的统一。您可以在Underscore's 的第4.3节中阅读有关此问题的一些详细信息。这本书提供了一个使用IsHCons的变通方法,但在这种情况下,我认为需要一个<:<证明会更简洁一些:

代码语言:javascript
复制
import shapeless.{::, Generic, HList, HNil}

case class Complex(re: Double, im: Double)

object Prod2 {
  def unapply[C, L <: HList, A, B](c: C)(implicit
    C: Generic.Aux[C, L],
    ev: L <:< (A :: B :: HNil)
  ) = Some((C.to(c).head, C.to(c).tail.head))
}

然后:

代码语言:javascript
复制
scala> val c = Complex(1.0, 2.0)
c: Complex = Complex(1.0,2.0)

scala> val Prod2(re, im) = c
re: Double = 1.0
im: Double = 2.0

这是令人失望的,但这是一个解决办法,你将需要一遍又一遍,如果你工作的形状,所以有它在你的工具箱是很好的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54432439

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档