2017-10-12 12 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)は、タイプHhList[String]に変換します。その後、tEncoder.encode(t)のベースケースに達するまで、残りのHListを再帰的にエンコードします。HNilで表され、結果はNil、つまり空のListです。中間結果は、2つのScala Listインスタンスを連結するために使用される演算子である++を使用して連結されます。

関連する問題