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转换到&gt;请解释一下。
答案 0 :(得分:1)
第2步是enc: Foo[R]
中的genericEncoder[Bippy, Bar :: HNil]
。
要解决此问题,请查看需要hlistEncoder[Bar, HNil]
的{{1}},即第3步。