2016-06-29 10 views
4

Angenommen, ich habe Container-MarkerhList als Parameter des Verfahrens mit vereinfachter Art Signatur

case class TypedString[T](value: String) 

wo einige value ID T für bestimmte Art darstellt.

Ich habe zwei Klassen

case class User(id: String) 
case class Event(id: String) 

Und ich habe eine Funktion, die ein paar Sachen tut:

def func[L <: HList](l: L)(...) {...} 

So kann ich es verwenden, wie

func[TypedString[User] :: TypedString[Event] :: HNil](
    TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil 
) 

(es ist für mich wichtig, (Typensignatur explizit beibehalten)

Die Frage ist: Wie oder func erstreckt sich ändern kürzere Art Signatur zu haben (wobei nur Typen Marker) wie:

func[User :: Event :: HNil](
    TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil 
) 

Antwort

2

Die shapeless.ops.hlist.Mapped Typklasse Sie die Beziehung eines hList L und andere hList, wo die Elemente gibt von L sind in einem Typkonstruktor eingewickelt.

Da Sie jetzt zwei Typen haben, die Art L Sie angeben möchten, und eine andere Art (die Elemente von L in TypedString verpackt), müssen wir den gleichen Trick verwenden wir in your previous question verwendet (dann, weil wir nicht wollen um alle Argumente auf einmal zu liefern, jetzt weil wir nur den ersten Typ angeben wollen).

import shapeless._ 
import ops.hlist.Mapped 

def func[L <: HList] = new PartFunc[L] 

class PartFunc[L <: HList] { 
    def apply[M <: HList](m: M)(implicit mapped: Mapped.Aux[L, TypedString, M]): M = m 
} 

Jetzt können Sie func verwenden, wie Sie wollen:

func[User :: Event :: HNil](
    TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil 
) 
// TypedString[User] :: TypedString[Event] :: HNil = 
//  TypedString(user id) :: TypedString(event id) :: HNil