Ok, I think I found the answer. The first tests seem to confirm this.
scala> :paste // Entering paste mode (ctrl-D to finish) import shapeless._ import shapeless.ops.hlist.At import shapeless.syntax.std.tuple._ final class myHListOps[L <: HList](l: L) { import hlistaux._ def extractors(implicit extractor : Extractor[_0, L,L]) : extractor.Out = extractor() } object hlistaux { trait Extractor[HF<:Nat, In <: HList, Remaining<: HList] extends DepFn0 { type Out <: HList } object Extractor { def apply[HL <: HList] (implicit extractor: Extractor[_0, HL,HL]): Aux[_0, HL, HL, extractor.Out] = extractor type Aux[HF<:Nat, In <: HList, Remaining<: HList, Out0 <: HList] = Extractor[HF, In, Remaining] { type Out = Out0 } //To deal with case where HNil is passed. not sure if this is right. implicit def hnilExtractor: Aux[_0, HNil, HNil, HNil] = new Extractor[_0, HNil, HNil] { type Out = HNil def apply(): Out = HNil } implicit def hSingleExtractor1[N<:Nat, In<:HList, H ] (implicit att : At[In, N]): Aux[N, In, H::HNil, At[In,N]::HNil] = new Extractor[N, In, H::HNil] { type Out = At[In,N]::HNil def apply(): Out = att::HNil } implicit def hlistExtractor1[N <: Nat, In<:HList, H, Tail<: HList] (implicit mt : Extractor[Succ[N], In, Tail], att : At[In, N]) :Aux[N, In, H::Tail, At[In,N]::mt.Out] = { new Extractor[N, In, H::Tail] { type Out = At[In,N]::mt.Out def apply(): Out = { att :: mt() } } } } } // Exiting paste mode, now interpreting. import shapeless._ import shapeless.ops.hlist.At import shapeless.syntax.std.tuple._ defined class myHListOps defined object hlistaux scala> val l = "Hello"::HNil l: shapeless.::[String,shapeless.HNil] = Hello :: HNil scala> val lo = new myHListOps(l).extractors lo: shapeless.::[shapeless.ops.hlist.At[shapeless.::[String,shapeless.HNil],shapeless._0],shapeless.HNil] = shapeless.ops.hlist$At$$anon$54@12d33d1c :: HNil scala> lo.head(l) res0: lo.head.Out = Hello scala> val m = 42::l m: shapeless.::[Int,shapeless.::[String,shapeless.HNil]] = 42 :: Hello :: HNil scala> val mo = new myHListOps(m).extractors mo: shapeless.::[shapeless.ops.hlist.At[shapeless.::[Int,shapeless.::[String,shapeless.HNil]],shapeless._0],shapeless.::[shapeless.ops.hlist.At[shapeless.::[Int,shapeless.::[String,shapeless.HNil]],shapeless.Succ[shapeless._0]],shapeless.HNil]] = shapeless.ops.hlist$At$$anon$54@5e181eeb :: shapeless.ops.hlist$At$$anon$55@1960690 :: HNil scala> mo.head(m) res3: mo.head.Out = 42 scala> mo.tail.head(m) res4: mo.tail.head.Out = Hello