Reputation: 1988
I want to find out if a particular class member is present in a given case class
or not.
Following does give me that answer, failing at compile time which is right. (credit to Travis Brown)
scala> def getIntId[A, R <: HList](a: A)(implicit
| gen: LabelledGeneric.Aux[A, R],
| sel: Selector.Aux[R, Witness.`'id`.T, Int]
| ): Int = sel(gen.to(a))
case class Foo(id: String)
case class Bar(id: Int, name: String)
scala> getIntId(Bar(123, "bar"))
res3: Int = 123
scala> getIntId(Foo("12345"))
<console>:15: error: could not find implicit value for parameter sel: shapeless.ops.record.Selector.Aux[R,Symbol with shapeless.tag.Tagged[String("id")],Int]
getIntId(Foo("12345"))
Now if I don't have a concrete type but T
to pass into getIntId
method, is there a way to get this to work with generic type T
?
Update
Say have a method called findIdFromType
as described below which takes in type T
(where T
will always be a some case class
). is it possible to make this work?
def findIdFromType[T](t:T) = {
getIntId(t) //as expected doesn't compile
}
Upvotes: 0
Views: 421
Reputation: 108101
getIntId
requires two implicit parameters.
If you need to call it in the context of a local method, you need to prove that those parameters exist in such context.
In order to do so, you have to propagate the implicit evidence, like this
def findIdFromType[A, R <: HList](a: A)(implicit
gen: LabelledGeneric.Aux[A, R],
sel: Selector.Aux[R, Witness.`'id`.T, Int]): Int = getIntId(a)
This of course is a completely useless example, but in case you want to perform other operations inside the wrapping method, this is the way to go: propagate the implicit evidence.
Upvotes: 2