Try something on these lines,
scala> import shapeless._, nat._, ops.hlist._ import shapeless._ import nat._ import ops.hlist._ scala> class Container[L <: HList](hl: L) { | def get(n: Nat)(implicit at: At[L, nN]): at.Out = hl[nN] | } defined class Container scala> val container = new Container(1 :: "foo" :: HNil) container: Container[shapeless.::[Int,shapeless.::[String,shapeless.HNil]]] = ... scala> container.get(_0) res1: Int = 1 scala> container.get(_1) res2: String = foo
The first key difference is that instead of typing hl like a regular HList that loses all the specific information about the types of elements, we parameterize the exact type of the argument and save its structure as L The second difference is that we use L to index an implicit instance of a class of type At , which is used for indexing in get .
Also note that since there is an implicit conversion from Int literals to Nat , you can write
scala> container.get(0) res3: Int = 1 scala> container.get(1) res4: String = foo
source share