Reputation: 533
Suppose I have container-marker
case class TypedString[T](value: String)
where value
represents some id for particular type T
.
I have two classes
case class User(id: String)
case class Event(id: String)
And I have a function which does some stuff:
def func[L <: HList](l: L)(...) {...}
So I can use it like
func[TypedString[User] :: TypedString[Event] :: HNil](
TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil
)
(it's important for me to keep type signature explicitly)
The question is: how to change or extends func to have shorter type signature (keeping only marker types) like:
func[User :: Event :: HNil](
TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil
)
Upvotes: 4
Views: 180
Reputation: 9820
The shapeless.ops.hlist.Mapped
type class gives you the relation of one HList L
and another HList where the elements of L
are wrapped in a type constructor.
Because you have now two types, the type L
you want to specify and another type (the elements of L
wrapped in TypedString
), we need to use the same trick we used in your previous question (then because we didn't want to supply all the arguments at once, now because we only want to specify the first type).
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
}
Now you can use func
as you wanted :
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
Upvotes: 2