2017-10-12 90 views
0

我已經在無形以下產品類型的實現:遞歸調用在哪裏?

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) 
} 

,它是用來如下:

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

在實例實施HList來看,我看不到遞歸調用的任何地方。因爲HList就像一個列表,它應該遞歸處理,但我無法將其配置出去。

回答

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。使用++連接中間結果,這是用於連接兩個Scala List實例的運算符。