You can wrap everything up in one method using the Zip
(or in this case Zip.Aux
) type class:
import shapeless._, shapeless.ops.hlist._
object mix extends Poly1 {
implicit def caseTuple[T] = at[(T, T)](t =>
if (util.Random.nextBoolean) t._2 else t._1)
}
def zipAndMix[L <: HList, Z <: HList](h1: L, h2: L)(implicit
zipper: Zip.Aux[L :: L :: HNil, Z],
mapper: Mapper[mix.type, Z]
) = (h1 zip h2) map mix
Now assuming you have h1
and h2
defined as in the question, you can write this:
scala> zipAndMix(h1, h2)
res0: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 5 :: b :: HNil
scala> zipAndMix(h1, h2)
res1: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 6 :: a :: HNil
scala> zipAndMix(h1, h2)
res2: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 5 :: a :: HNil
And so on. This will work in either 2.0.0-M1 or the latest snapshot, although (as I've noted in a comment above) you may run into confusing issues on the way before this bug was fixed.