我正在阅读这段代码很长一段时间。我把它键入REPL,它也可以。
但我不知道这里发生了什么。为什么以及如何运作!!!
import shapeless._
case class Size[L <: HList](get : Int)
object Size {
implicit val hnilSize = Size[HNil](0)
implicit def hconsSize[H, T <: HList](implicit tailSize: Size[T]) =
Size[H :: T](1 + tailSize.get)
def apply[L <: HList](l : L)(implicit size: Size[L]) : Int = size.get
}
Size(1 :: "Foo" :: true :: HNil)
有人可以一步一步地解释这一点,并帮助我理解这里发生了什么。
答案 0 :(得分:7)
是的,那个很厚的东西。
这里的心灵弯曲是hconsSize
是递归的,而不是实际的自我指涉。
apply
和hconsSize
都隐含了类型Size[X]
。只有两个含义可以适合该法案:
hnilSize
,但仅当X
类型为HNil
hconsSize
本身因此apply
引入hconsSize
隐式,它将1加到堆栈中并引入另一个hconsSize
隐式(不一定按此顺序)。这一直持续到我们遇到HNil
类型的元素。然后引入hnilSize
隐式,get
为零,展开堆栈并将所有这些1加起来。
结果:无形HList中的元素数。