Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map Shapeless hlist type F[T1] :: ... :: F[Tn] :: HNil to the type T1 :: ... :: Tn :: HNil (type level sequencing)

I'm building a generic function that takes in a HList of the form F[T1] :: ... :: F[Tn] :: HNil, converts that into a F[T1 :: ... :: Tn :: HNil] and then needs to pass that into a block that was passed in. However, in order for that to work, I need to extract the HList type in that F[_]. I've found something remotely relevant under Shapeless' hlistconstraints:

/**
 * Type class witnessing that every element of `L` has `TC` as its outer type constructor. 
 */
trait UnaryTCConstraint[L <: HList, TC[_]]

...but this can only be used to verify that the hlist passed in is indeed made up of just F[_]; there seems to be no way however to extract that _ bit so to say to a hlist of its own.

Where should I be looking to find something to do the job? Or should I just not expect to find anything out of the box and instead build the type computation myself?

Disclosure: this question is an auxilliary to Generic transform/fold/map over tuple/hlist containing some F[_] but is nevertheless at least as useful as a standalone question, in my opinion.

like image 376
Erik Kaplun Avatar asked Oct 21 '14 20:10

Erik Kaplun


1 Answers

Looks like Sequencer already does this:

import scala.language.higherKinds

class Wrap[TC[_]] {
  def foo[L1 <: HList, L2 <: HList](xs: L1)(implicit
    seq: Sequencer.Aux[L1, TC[L2]] // L2 is the type we're looking for
  ): L2 = ???
}

val ret = new Wrap[Option].foo(1.some :: 2.some :: HNil)
// ret now has type Int :: Int :: HNil

...but I'm currently unable to think of a way to make this nicer by

  • getting rid of the wrapper class;
  • having Scala infer TC to be Option.

Note: I think this is somewhat useful as an answer but I'm not accepting it — hoping someone will come up with a more generic and nicer looking solution.

like image 191
Erik Kaplun Avatar answered Sep 28 '22 20:09

Erik Kaplun