trolley813
trolley813

Reputation: 932

shapeless - using Mapped for wrapping to a type with 2 or more parameters

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

Answers (1)

Dmytro Mitin
Dmytro Mitin

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

Related Questions