Where is the recursive call?

时间:2017-10-12 09:58:28

标签: scala recursion shapeless

I have following product type implementation in shapeless:

trait CsvEncoder[A] {
  def encode(value: A): List[String]
}

implicit val hnilEncoder: CsvEncoder[HNil] =
createEncoder(_ => Nil)


implicit def hlistEncoder[H, T <: HList](
                                        implicit
                                        hEncoder: CsvEncoder[H],
                                        tEncoder: CsvEncoder[T]
                                      ): CsvEncoder[H :: T] =
createEncoder {
  case h :: t =>
    hEncoder.encode(h) ++ tEncoder.encode(t)
}

and it is used as follow:

val reprEncoder: CsvEncoder[String :: Int :: Boolean :: HNil] =
  implicitly
println(reprEncoder.encode("abc" :: 123 :: true :: HNil))

Looking at the instance implementation of HList, I can not see the recursive call anywhere. Because HList is like a list, it should process recursively but I can not configure it out where that happened.

1 个答案:

答案 0 :(得分:3)

它发生在tEncoder.encode(t)。我们特别要分析以下代码:

case h :: t =>
  hEncoder.encode(h) ++ tEncoder.encode(t)   

case h :: t解构其头部和尾部的HList。然后hEncoder.encode(h)h类型的值H转换为List[String]。然后tEncoder.encode(t)递归编码剩余的HList,直到它到达由HNil表示的基本案例,其结果为Nil,即为空List。中间结果使用++连接,List是用于连接两个Scala String splitme = "mom.girl, dad:boy [ girl, aunt ] granny";实例的运算符。