The problem isn't type erasure or anything tricky to do with Shapeless—it's just that the inferred type of a conditional expression is the least upper bound of the type of the two branches, and in this case that's Any
. You can see the same thing happen with a plain old polymorphic method:
scala> def foo[A](a: A) = if (true) a else false
foo: [A](a: A)Any
As a side note, it would be a little more elegant (and idiomatic) to match on the structure of the HList
instead of requiring an instance of the IsHCons
type class:
object test extends Poly1 {
implicit def default[H, T <: HList] = at[H :: T](_.head)
}
This does exactly the same thing as your "clean" example.