1
Shapeless Guideは多かれ少なかれ次のコードを提供します。私はCsvEncoder
からFoo
に名前を変更しました。「多様な暗黙的な展開」の理解
$cat build.sbt
scalaVersion := "2.12.1"
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.3.2"
)
と
$cat src/main/scala/net/Foo.scala
package net
import shapeless.{::, Generic, HList, HNil, Lazy}
object Foo {
def apply[A](implicit ev: Foo[A]): Foo[A] = ev
def instance[A](f: A => List[String]): Foo[A] =
new Foo[A] {
override def encode(x: A): List[String] = f(x)
}
implicit val hnilEncoder: Foo[HNil] =
instance[HNil](hnil => Nil)
implicit def hlistEncoder[H, T <: HList](
implicit hEncoder: Foo[H],
tEncoder: Foo[T]
): Foo[H :: T] =
instance[H :: T] {
case h :: t => hEncoder.encode(h) ++ tEncoder.encode(t)
}
implicit def genericEncoder[A, R](
implicit gen: Generic[A] { type Repr = R },
enc: Foo[R]): Foo[A] =
instance[A] { a =>
enc.encode(gen.to(a))
}
}
case class Bar(baz: Int, qux: String)
case class Bippy(bar: Bar)
trait Foo[A] {
def encode(x: A): List[String]
}
私は、暗黙のFoo[Bippy]
を解決しようとした:
> console
[info] Starting scala interpreter...
[info]
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.
scala> import net.Foo
import net.Foo
scala> import net._
import net._
scala> implicitly[Foo[Bippy]]
<console>:16: error: diverging implicit expansion for type net.Foo[net.Bippy]
starting with method genericEncoder in object Foo
implicitly[Foo[Bippy]]
^
テキストは、次の解決手順は、コンパイル時の障害が発生する前に行われていることを述べて:
Foo[Bippy] // 1
Foo[Bar :: HNil] // 2
Foo[Bar] // 3
Foo[Int :: String :: HNil] // 4 uh oh
しかし、私は2 - > 3からの移行を理解していません。説明してください。
である、
hEncoder: Foo[Bar]
を必要とするhlistEncoder[Bar, HNil]
を見て、**ことを解決するにはtek/splainは、暗黙の問題を多く理解するのに役立ちます。 – Haspemulator