type erasure in a poly function, scala

212 views Asked by At

So I wanted to make a map function over a HList, but I need to check for some conditions inside the applying function. Smth like:

object test extends Poly1 {
    implicit def default[L <: HList](implicit head: ops.hlist.IsHCons[L]) = 
    at[L](t => {
        if(true) t.head else false //here some condition    
    })
}

As the result, we loose all information about type of t.head element; btw if we build "clean" function:

object test extends Poly1 {
    implicit def default[L <: HList](implicit head: ops.hlist.IsHCons[L]) = 
    at[L](t => t.head)
}

Then, obviously, it's all ok.

So the question is: how to deal with it, and to make such sort of function (if it's possible) or I should search another way? Why here can be type erasure?

1

There are 1 answers

2
Travis Brown On BEST ANSWER

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.