title: Using shapeless HLists with invariant containers
body: <p>Suppose the elements of an <code>HList</code> are subclasses of a generic trait.   Each element is contained in <code>case class Box[E](elem E)</code>. That <code>Box</code> is <em>invariant</em> in <code>E</code>  causes problems with mapping a <code>poly1</code> over <code>HList</code>, selecting an element by its parent trait, etc. Here's an example:</p>
  
  <pre><code>import shapeless._
  
  trait Drink[+A]{ def v: A}
  
  case class Water(v: Int) extends Drink[Int]
  case class Juice(v: BigDecimal) extends Drink[BigDecimal]
  case class Squash(v: BigDecimal) extends Drink[BigDecimal]
  
  
  case class Box[E](elem: E) // NB! invariance in E
  
  object pour extends Poly1{
  
    implicit def caseInt[A &lt;: Box[Drink[Int]]] =  at[A](o =&gt; Box(o.elem.v * 2))
    implicit def caseDec[A &lt;: Box[Drink[BigDecimal]]] = at[A](o =&gt; Box(o.elem.v + 5.0))
  }
  
  
  object Proc {
  
    type I = Box[Water] :: Box[Squash] :: Box[Juice] ::  HNil
    type O = Box[Int] :: Box[BigDecimal] :: Box[BigDecimal] :: HNil
  
    val drinks: I = Box(Water(10)) :: Box(Squash(15.0)) :: Box(Juice(2.0)) :: HNil
  
    def make()(implicit m: ops.hlist.Mapper.Aux[pour.type, I, O]): O = drinks.map(pour)
  }
  
  
  object Main extends App{
    override def main(args: Array[String]): Unit =  Proc.make()
  }
  </code></pre>
  
  <p>*The function <code>pour</code> applies the answer by @Jasper_M to <a href="https://stackoverflow.com/questions/48120465/mapping-over-hlist-with-subclasses-of-a-generic-trait">Mapping over HList with subclasses of a generic trait</a>.</p>
  
  <p>This code leads to 
  <code>Error:(38, 22) could not find implicit value for parameter m: shapeless.ops.hlist.Mapper.Aux[pour.type,Proc.I,Proc.O] 
   Proc.make()</code>. 
  Also, filtering <code>Proc.drinks.covariantFilter[Box[Drink[Int]]]</code> produces <code>HNil</code>. (This filter implements the answer by @Travis Brown to  <a href="https://stackoverflow.com/questions/25713668/do-a-covariant-filter-on-an-hlist">Do a covariant filter on an HList</a>.)</p>
  
  <p>Defining <code>Box[+E]</code>, which solves the problems, is not possible in my project. A naive solution -- to have a case in the <code>pour</code> for each subclass of <code>Drink</code> -- does not scale. (This could be made to work by passing monomorphic functions to <code>pour</code>, which I don't know how.)</p>
  
  <p>Could there be a more sensible approach to mapping or filtering over HLists in this set-up? </p>