When you write IsHCons.Aux[L, TypedMap, L] , you ask for evidence that hlist L has a head TypedMap and tail L , which means it is an infinite hlist, which is impossible, since Scala does not allow this kind of arbitrarily recursive type ( try to write something like type Foo = Int :: Foo , for example, you will get an "illegal circular reference" error). This is also probably not what you want.
In general, you are unlikely to use IsHCons lot in Shapeless, since it is almost always better to just specify the structure you want in the type. For example, the following two definitions do the same thing:
import shapeless._, ops.hlist.IsHCons def foo[L <: HList](l: L)(implicit ev: IsHCons[L]) = ev.head(l)
and
def foo[H, T <: HList](l: H :: T) = l.head
But the second one is obviously preferable (it is more clear, it does not require an additional instance of the instance class, which can be found at compile time, etc.), and you can almost always write everything that you try to do in this way.
Also note that requiring an IsHCons instance means that recursion will not work here, as indicated, you cannot invoke get on HNil , since the compiler cannot prove that it is HCons (because it is not).
Are you sure you need an hlist? If you require all hlist members to be of type TypedMap , you could also use Shapeless Sized (if you want the type to be fixed in length) or even just the old List .
If you really want to use HList here, I would suggest writing a new class like:
trait FindField[L <: HList] { def find(key: IntegerField, l: L): Option[Int] } object FindField { implicit val findFieldHNil: FindField[HNil] = new FindField[HNil] { def find(key: IntegerField, l: HNil) = None } implicit def findFieldHCons[H <: TypedMap, T <: HList](implicit fft: FindField[T] ): FindField[H :: T] = new FindField[H :: T] { def find(key: IntegerField, l: H :: T) = if (l.head.head == key) Some(l.head.tail.head) else fft.find(key, l.tail) } } def get[L <: HList](key: IntegerField, l: L)(implicit ffl: FindField[L] ): Option[Int] = ffl.find(key, l)
And then:
scala> get(IntegerField("year"), test) res3: Option[Int] = Some(23) scala> get(IntegerField("foo"), test) res4: Option[Int] = None
This is a fairly common pattern in Shapeless - you inductively describe how to perform an operation in an empty hlist, then in an hlist with a head preceded by a tail that you know how to perform the operation, etc.