2017-01-15 4 views
0

ich getippt, mehr oder weniger, die Last Typklasse von shapeless‚s Last:formlos erkunden die `Last` Typ Klasse

import shapeless.{HList, HNil, ::} 

trait Last[H <: HList] { 
    type Out 
    def last(in: H): Out 
} 

Dann tippte ich aus dem, wie ich sie verstehe, Typklasse Instanzen Last für HList:

object Last { 
    type Aux[L <: HList, O] = Last[L] { type Out = O } 

    // arrived at the truly `last` item, i.e. `H` 
    implicit def singleLast[H]: Aux[H :: HNil, H] = new Last[H :: HNil] { 
    override type Out = H 
    override def last(in: H :: HNil): H = in.head 
    } 

    // I believe this is the inductive step 
    implicit def hlistLast[H, T <: HList, OutT] 
    (implicit lt : Last.Aux[T, OutT]): Aux[H :: T, OutT] = 
    new Last[H :: T] { 
     type Out = OutT 
     def apply(l : H :: T): Out = lt(l.tail) 
    } 
} 

Allerdings verstehe ich nicht, warum es kompilieren fehlschlägt:

[error] /Users/kevinmeredith/Workspace/shapeless-sandbox/src/ 
     main/scala/net/ops.scala:17: net.Last.Aux[T,OutT] does not take parameters 
[error]  def apply(l : H :: T): Out = lt(l.tail) 
[error]         ^
[error] one error found 
[error] (compile:compileIncremental) Compilation failed 

Wie kann ich diesen Kompilierungsfehler beheben?

Antwort

2

Die tatsächliche formlos Implementierung von Last wie folgt aussieht:

trait Last[H <: HList] { 
    type Out 
    def apply(in: H): Out 
} 

Sie apply-last geändert, aber in hlistLast versuchen Sie noch apply (sowohl durch ihn zu definieren und deren Verwendung auf lt) zu verwenden:

Der Compilerfehler kommt von versuchen, lt.apply zu verwenden, wenn es nicht existiert. Es wäre in diesem Fall hilfreicher gewesen, wenn der Compiler Ihnen zuerst gesagt hätte, dass last nicht implementiert wurde.

+0

Hmm. Wie kann ich es reparieren? –

+1

Benennen Sie 'apply' in' hlistLast' in 'last' um oder benennen Sie' last' in 'trait /' singleLast' um. –