Shapeless provides a ToList
implicit which is used, unsurprisingly, to convert HLists to Lists.
In order to do that, it must first calculate the LUB (least upper bound) of the types in the HList, and that's something you can use:
import shapeless.ops.hlist.ToList
class Mappings[L <: HList, Lub](mappings:L)(implicit toList: ToList[L, Lub]) {
...
}
L
goes in, implicit resolution discovers the one (and only) valid ToList
instance constrained by that L
, the Lub
type of which is pulled out.
That's not enough though, as Lub
will be KeyMapping[String]
, whereas all you want is the String
part. As usual with shapeless, the solution is to add another implicit:
class Mappings[L <: HList, Lub, KeyType](mappings:L)(
implicit
val toList: ToList[L, Lub],
val kt: Lub <:< KeyMapping[KeyType]
) {
val k: KeyType = null.asInstanceOf[KeyType]
}
(the implicits don't need to be val
s, but it helps if they are when you're exploring things in the REPL)
What this asserts is that Lub
corresponds to the type KeyMapping[KeyType]
(e.g. it's a subtype or the exact same type), where KeyType
is, as yet, unknown. Again, there's only one valid solution to the constraints specified, and the KeyType
parameter is pulled out as being String
.
I have no idea how you plan on implementing k
, but you may find that having that toList
instance helps you to do so, as it allows you to now invoke mappings.toList