1

Shapeless の を使用して、Scala の暗黙関数で次の問題が発生しました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

上記のコードはコンパイルされません。報告する

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]]

この暗黙的なインスタンスを派生させることはまったく問題ありません。

4

2 に答える 2

1

残念ながら、コンパイラはABここで推論するために必要な統合を実行するほどスマートではありません。この問題の詳細については、Underscore のType Astronaut's Guide to Shapelessのセクション 4.3 を参照してください。この本は を使用した回避策を提供していますが、この場合、証明を要求する方が少しきれいIsHConsだと思います:<:<

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 を使用する場合に何度も必要になる回避策であるため、ツールボックスに入れておくとよいでしょう。

于 2019-01-30T08:34:48.813 に答える