I donโt think that you will get exactly what you want, since Scala implicit resolution happens before type input (but who knows - people always amaze me in Scala).
(Side note: CanBuildFrom / breakOut supports something similar to what you are asking for, but I see no way to make it work in this situation, since the type of source limits the availability of instances.)
There is a fairly standard workaround for this kind of situation, although it involves using an auxiliary class to approximate the partial use of type parameters. Suppose you have a fairly simple type class that captures your conversion logic:
import java.net.URL import shapeless._ trait Convert[I <: HList, O <: HList] { def apply(i: I): O } object Convert extends LowPriorityConvertInstances { implicit val convertHNil: Convert[HNil, HNil] = new Convert[HNil, HNil] { def apply(i: HNil): HNil = i } implicit def convertHConsURL[T <: HList, TO <: HList](implicit c: Convert[T, TO] ): Convert[String :: T, URL :: TO] = new Convert[String :: T, URL :: TO] { def apply(i: String :: T): URL :: TO = new URL(i.head) :: c(i.tail) } } sealed class LowPriorityConvertInstances { implicit def convertHCons[H, T <: HList, TO <: HList](implicit c: Convert[T, TO] ): Convert[H :: T, H :: TO] = new Convert[H :: T, H :: TO] { def apply(i: H :: T): H :: TO = i.head :: c(i.tail) } }
Now you can try something like this:
def convert[I <: HList, O <: HList](i: I)(implicit c: Convert[I, O]): O = c(i)
But there are two problems. First, if you specify type parameters, you will always get a conversion that turns each line into a URL. You can override this behavior by explicitly providing both type parameters, but ugh.
We can (sort of) improve this situation with a helper class:
class PartiallyAppliedConvert[O <: HList] { def apply[I <: HList](i: I)(implicit c: Convert[I, O]): O = c(i) } def convert[O <: HList]: PartiallyAppliedConvert[O] = new PartiallyAppliedConvert[O]
Now you can write the following:
scala> val mapped = convert[String :: URL :: HNil](list) mapped: shapeless.::[String,shapeless.::[java.net.URL,shapeless.HNil]] = Stackoverflow :: https://stackoverflow.com/q :: HNil
This is not quite what you requested, but it is pretty close, since the only type we need to explicitly indicate is the desired type of target.