未应用中未找到 Scala 无形的 Generic.Aux 隐式参数 [英] Scala shapeless Generic.Aux implicit parameter not found in unapply

查看:42
本文介绍了未应用中未找到 Scala 无形的 Generic.Aux 隐式参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I encountered the following problem with implicits in Scala, using Shapeless's Generic.Aux:

  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

上面的代码无法编译.它报告

The code above does not compile. It reports

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

但是,如果我手动执行

implicitly[Generic.Aux[Complex, Double :: Double :: HNil]]

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

it is perfectly OK to derive this implicit instance.

推荐答案

不幸的是,编译器不够聪明,无法执行推断 AB<所需的统一/code> 在这里.您可以在 Underscore 键入宇航员的无形指南.这本书提供了一种使用 IsHCons 的解决方法,但在这种情况下,我认为需要一个 <:< 证明更简洁:

Unfortunately the compiler simply isn't smart enough to perform the unification that would be necessary to infer A and B here. You can read about some of the details of this problem in section 4.3 of Underscore's Type Astronaut’s Guide to Shapeless. The book provides a workaround using IsHCons, but in this case I think requiring a <:< proof is a little cleaner:

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))
}

然后:

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

令人失望,但如果您使用 Shapeless,这是一种您需要反复使用的解决方法,因此最好将它放在您的工具箱中.

It's disappointing, but this is a workaround you'll need over and over if you work with Shapeless, so it's good to have it in your toolbox.

这篇关于未应用中未找到 Scala 无形的 Generic.Aux 隐式参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆