无形-使用映射将其包装为具有2个或更多参数的类型

时间:2018-09-24 09:52:13

标签: scala shapeless

例如,我有

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]

不能正常工作,因为TD的类型参数,因此这样的定义必须在D的主体内,因此在{{1 }}的类型参数(即在方括号内)。

因此,我应该编写自己的D实现还是为此提供一些内置解决方案?

1 个答案:

答案 0 :(得分:1)

如果您的麻烦是C拥有2个参数而不是1个参数,并且您想避免定义别名,则可以使用type lambda

Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]

kind-projector编译器插件

Mapped.Aux[L, C[T, ?], M]

通常在类似{p>的隐式定义中使用shapeless.ops.hlist.Mapped之类的type classes

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] = ???
}