In shapeless, have two lists such that one contains typeclasses of the other

scala, shapeless

Solution

`Mapped` provides precisely this constraint without the additional need for `Length`. From the documentation:

Type class witnessing that the result of wrapping each element of `HList` `L` in type constructor `F` is `Out`.

Here's how it looks in 1.2.4:

import shapeless._

def foo[L1 <: HList, L2 <: HList](l1: L1, l2: L2)(implicit
  ev: MappedAux[L1, Ordering, L2]
) = ()

val l1 = 1 :: 1.2 :: "hello" :: HNil
val l2 = Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil
val l3 = Ordering[Int] :: Ordering[Double] :: Ordering[Char] :: HNil

And then:

scala> foo(l1, l2)

scala> foo(l1, l3)
<console>:17: error: could not find implicit value for parameter ev: ...

As expected. For 2.0 just add a `shapeless.ops.hlist._` import and replace `MappedAux` with `Mapped.Aux` and you're ready to go.

Problem

In shapeless I'm trying to write a function such that takes two HLists `l1` and `l2` of arbitrary length which exhibit the following properties: - Length of `l1` and `l2` are the same. - `l2` contains the exact types of `l1`, wrapped in a constant outer type constructor. So, if `l1` was ``` 1 :: 1.2 :: "hello" :: HNil` ``` `l2` could be ``` Ordering[Int] :: Ordering[Double] :: Ordering[String] :: HNil ``` Using `UnaryTCConstraint` and `LengthAux` lets me constrain the lengths and require a static outer constructor for `l2`, however having them conform has become a problem. Any ideas on how I could go about it?

Original source