Reputation: 932
For example, I have
class C[T, U] { ... }
class D[T, L <: HList, M <: HList] { ... }
I want that if the L
is for instance U1 :: U2 :: U3 :: HNil
, the type of M
to be C[T, U1] :: C[T, U2] :: C[T, U3] :: HNil
(i.e. wrapping into constructor of C
, where the T
parameter is fixed, and U
runs through the L
list). However, Mapped[L, C, M]
does not work because it requires C
to have only 1 type parameter, and it has 2.
Defining an alias
type C1[U] = C[T, U]
does not work as well because T
is a type parameter of D
, so such a definition must be inside the body of D
, and so it's not visible from D
's type parameters (i.e. from inside square brackets).
So, should I write my own implementation of Mapped
or there exist some built-in solutions to this?
Upvotes: 0
Views: 83
Reputation: 51723
If your trouble is C
having 2 parameters instead of 1 and you want to avoid defining an alias you can use type lambda
Mapped.Aux[L, ({ type l[U] = C[T, U] })#l, M]
or kind-projector compiler plugin
Mapped.Aux[L, C[T, ?], M]
Normally type classes like shapeless.ops.hlist.Mapped
should be used in implicit definitions 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] = ???
}
Upvotes: 1