2016-06-08 27 views
6

Sto leggendo questo codice per molto tempo. L'ho inserito in REPL e funziona altrettanto bene.Chi può spiegare il significato di questo codice scala

ma non ho idea di cosa sta succedendo qui. Perché e come funziona anche questo !!!

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) 

Qualcuno può spiegare questo passo dopo passo e aiutarmi a capire cosa sta succedendo qui.

risposta

7

Sì, è roba piuttosto spessa.

Il mind bender è che hconsSize è ricorsivo senza essere autoreferenziale.

Entrambi apply e hconsSize inserire un tipo implicito Size[X]. Ci sono solo due impliciti che potrebbero andare bene quella fattura:

  1. hnilSize, ma solo se X è di tipo HNil
  2. hconsSize stesso

Così apply tira in hconsSize implicita, che aggiunge 1 al impila e tira in un altro hconsSize implicito (non necessariamente in questo ordine). Questo continua finché non incontriamo un elemento di tipo HNil. Quindi viene implicato l'input implicito hnilSize, lo get è zero, lo stack viene srotolato e tutti gli 1 vengono sommati.

Risultato: numero di elementi nell'HL senza forma.