4

假设我有容器标记

case class TypedString[T](value: String)

wherevalue代表特定类型的一些 id T

我有两节课

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
)
4

1 回答 1

2

shapeless.ops.hlist.Mapped类型类为您提供了一个 HList 和另一个 HList 的关系,其中L的元素L被包装在类型构造函数中。

因为您现在有两种类型,一种是L您要指定的类型,另一种是另一种类型(LWrapped in的元素TypedString),我们需要使用我们在上一个问题中使用的相同技巧(然后因为我们不想提供所有参数一次,现在因为我们只想指定第一种类型)。

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
于 2016-06-29T09:45:47.713 回答