假设我有容器标记
case class TypedString[T](value: String)
其中value表示特定类型T的某个id.
我有两节课
case class User(id: String)
case class Event(id: String)
我有一个功能,它可以做一些事情:
def func[L <: HList](l: L)(...) {...}
所以我可以像使用它一样
func[TypedString[User] :: TypedString[Event] :: HNil](
TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil
)
(明确保留类型签名对我来说很重要)
问题是:如何更改或扩展func以使类型签名更短(仅保留标记类型),如:
func[User :: Event :: HNil](
TypedString[User]("user id") :: TypedString[Event]("event id") :: HNil
)
最佳答案 shapeless.ops.hlist.Mapped类型类为您提供一个HList L和另一个HList的关系,其中L的元素包含在类型构造函数中.
因为你现在有两种类型,你想要指定的类型L和另一种类型(L包含在TypedString中的元素),我们需要使用我们在your previous question中使用的相同技巧(那时因为我们不想提供所有的一下子参数,现在因为我们只想指定第一种类型).
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
}
现在你可以根据需要使用func:
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