2013-10-28 21 views
7

Wie kann ich einige HList als Argument übergeben? So kann ich in einer solchen Art und Weise machen:Heterogene Argumente in einer Scala-Funktion

def HFunc[F, S, T](hlist: F :: S :: T :: HNil) { 
    // here is some code 
} 

HFunc(HList(1, true, "String")) // it works perfect 

Aber wenn ich eine lange Liste, und ich weiß nicht, nichts darüber, wie kann ich einige Operationen auf sie machen? Wie kann ich Argument übergeben und nicht seinen Typ verlieren?

+1

Welche Art von Operationen möchten Sie im Methodenrumpf ausführen? –

+0

hm, einige typabhängige Objekte können in dieser Liste gespeichert werden, und ich möchte keine Informationen über Objekttypen verlieren. Also brauche ich mb alle Operationen auf 'HLists '-' map, head, etc ... ':) – DaunnC

Antwort

8

Es hängt von Ihrem Anwendungsfall ab.

HList ist für Typ-Level-Code nützlich, so dass Sie sollten nicht nur HList, sondern auch alle notwendigen Informationen wie diese auf Ihre Methode übergeben:

def hFunc[L <: HList](hlist: L)(implicit h1: Helper1[L], h2: Helper2[L]) { 
    // here is some code 
} 

Zum Beispiel, wenn Sie Ihre Hlist und mapreverse über Ergebnis sollten Sie Mapper und Reverse wie folgt verwenden:

import shapeless._, shapeless.ops.hlist.{Reverse, Mapper} 

object negate extends Poly1 { 
    implicit def caseInt = at[Int]{i => -i} 
    implicit def caseBool = at[Boolean]{b => !b} 
    implicit def caseString = at[String]{s => "not " + s} 
} 

def hFunc[L <: HList, Rev <: HList](hlist: L)(
           implicit rev: Reverse[L]{ type Out = Rev }, 
             map: Mapper[negate.type, Rev]): map.Out = 
    map(rev(hlist)) // or hlist.reverse.map(negate) 

Verbrauch:

hFunc(HList(1, true, "String")) 
//String :: Boolean :: Int :: HNil = not String :: false :: -1 :: HNil 
+0

y, sehe ich zum Beispiel:' def hFunc [L <: HList] (hlist: L) (implizite m: TypeTag [L]) 'und es gibt alle Informationen zum Objekttyp in' m'; aber ich kann 'hlist.head' nicht machen, weil' hlist' Argument tatsächlich einen anderen Typ hat; und es wird ein Fehler ausgegeben (wenn 'hlist.head' gemacht wird):' konnte keinen impliziten Wert für den Parameter c finden: shapeless.IsHCons [L] ' – DaunnC

+0

@DaunnC: Nicht' TypeTag'. Sie sollten "Mapper" für "map", "Reverse" für "reverse" und so weiter verwenden. – senia

+0

w0w thx! Ich werde es versuchen; Hast du ein paar Links für mich zu lernen? – DaunnC