shapeless - 使用 Mapped 包装到具有 2 个或更多参数的类型
shapeless - using Mapped for wrapping to a type with 2 or more parameters
比如我有
class C[T, U] { ... }
class D[T, L <: HList, M <: HList] { ... }
我希望如果 L
例如 U1 :: U2 :: U3 :: HNil
,M
的类型为 C[T, U1] :: C[T, U2] :: C[T, U3] :: HNil
(即包装到 C
的构造函数中,其中 T
参数是固定的,U
遍历 L
列表)。但是,Mapped[L, C, M]
不起作用,因为它要求 C
只有 1 个类型参数,而它有 2 个。
定义别名
type C1[U] = C[T, U]
也不起作用,因为 T
是 D
的类型参数,所以这样的定义必须在 D
的主体内,因此它在 D
中不可见=23=]的类型参数(即来自方括号内)。
那么,我应该自己编写 Mapped
的实现还是存在一些内置的解决方案?
如果您的问题是 C
有 2 个参数而不是 1 个,并且您想避免定义别名,您可以使用 type lambda
Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]
或kind-projector编译器插件
Mapped.Aux[L, C[T, ?], M]
通常 type classes like shapeless.ops.hlist.Mapped
应该用于隐式定义 like
class C[T, U] {
// ...
}
class D[T, L <: HList, M <: HList] {
// ...
}
object D {
implicit def mkInstanceOfD[T, L <: HList, M <: HList](implicit
mapped: Mapped.Aux[L, C[T, ?], M]): D[T, L, M] = ???
//implicit def mkInstanceOfD[T, L <: HList, M <: HList](implicit
// mapped: Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]): D[T, L, M] = ???
}
比如我有
class C[T, U] { ... }
class D[T, L <: HList, M <: HList] { ... }
我希望如果 L
例如 U1 :: U2 :: U3 :: HNil
,M
的类型为 C[T, U1] :: C[T, U2] :: C[T, U3] :: HNil
(即包装到 C
的构造函数中,其中 T
参数是固定的,U
遍历 L
列表)。但是,Mapped[L, C, M]
不起作用,因为它要求 C
只有 1 个类型参数,而它有 2 个。
定义别名
type C1[U] = C[T, U]
也不起作用,因为 T
是 D
的类型参数,所以这样的定义必须在 D
的主体内,因此它在 D
中不可见=23=]的类型参数(即来自方括号内)。
那么,我应该自己编写 Mapped
的实现还是存在一些内置的解决方案?
如果您的问题是 C
有 2 个参数而不是 1 个,并且您想避免定义别名,您可以使用 type lambda
Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]
或kind-projector编译器插件
Mapped.Aux[L, C[T, ?], M]
通常 type classes like shapeless.ops.hlist.Mapped
应该用于隐式定义 like
class C[T, U] {
// ...
}
class D[T, L <: HList, M <: HList] {
// ...
}
object D {
implicit def mkInstanceOfD[T, L <: HList, M <: HList](implicit
mapped: Mapped.Aux[L, C[T, ?], M]): D[T, L, M] = ???
//implicit def mkInstanceOfD[T, L <: HList, M <: HList](implicit
// mapped: Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]): D[T, L, M] = ???
}