Subtype polymorphism in shapeless mapping

scala, shapeless

Solution

`~>` works with exact types. If you want a `Poly1` for any subtype of `Iterable` you should create it like this:

object iterateOverHList extends Poly1 {
  implicit def iterable[T, L[T] <: Iterable[T]] = at[L[T]](_.iterator)
}

You could also create a `Poly1` that works on some types that could be treated as `Iterable` like this:

import scala.collection.generic.IsTraversableOnce
object iterateOverHList extends Poly1 {
  implicit def iterable[L](implicit i: IsTraversableOnce[L]) =
    at[L](i.conversion(_).toIterator)
}

val x = "abc" :: List(1,2,3) :: HNil
val xIt = x map iterateOverHList
// xIt: shapeless.::[Iterator[Char],shapeless.::[Iterator[Int],shapeless.HNil]] = non-empty iterator :: non-empty iterator :: HNil

Problem

I've constructed the following: ``` import shapeless._ import poly._ object Main { def main(args: Array[String]) = { object iterateOverHList extends (List ~> Iterator) { def apply[T](it: List[T]) = it.iterator } val x = List(1,2,3) :: List("cat","dog") :: HNil val xIt = x map iterateOverHList } } ``` The above code works great and is awesome. However, I still want more. I would like to, rather than specifying that my HList will contain Lists, allow any Iterable. Like this: ``` import shapeless._ import poly._ object Main { def main(args: Array[String]) = { object iterateOverHList extends (Iterable ~> Iterator) { def apply[T](it: Iterable[T]) = it.iterator } val x = List(1,2,3) :: List("cat","dog") :: HNil val xIt = x map iterateOverHList } } ``` This second version fails to compile, with the message "could not find implicit value for parameter mapper: shapeless.ops.hlist.Mapper[iterateOverHList.type,shapeless.::[List[Int],shapeless.::[List[String],shapeless.HNil]]]". The subtype polymorphism I'm expecting here, that a function that works on Iterable should work on List, is failing for some reason. Why is that? Is there a way for me to get around this problem, or will my own greed be my undoing?

Original source

Related problems