Reputation: 1241
I have a use case in my library where an HList A
is considered convertible to HList B
if it contains all the elements of HList B
regardless of ordering. I need there to be an implicit conversion between the two such as this:
// implicit arguments omitted for readability
implicit def toOther[A <: HList, B <: HList](l: A): B = l.filter[B].align[B]
but HList.filter
returns HNil
if supplied with a type argument of type HList. how else can I convert A to B?
Edit
Here is an attempt to implement the functionality In case you need boiler plate to copy and paste:
import shapeless.{::, HList, HNil}
import shapeless.ops.hlist.Align
implicit def toOther[A <: HList, B <: HList](v: A)(implicit a: Align[A, B]): B = v.align[B]
def method(p: Int :: Boolean :: HNil): Unit = println("success")
val list = false :: 7 :: HNil
// works on it's own. (only for Hlists of same length though)
toOther[Boolean :: Int :: HNil,Int :: Boolean :: HNil](list)
//doesn't work! Weird!
// also if it did, it only would for two HLists of the same length
method(list)
Upvotes: 2
Views: 187
Reputation: 15086
For the conversion part, I think what you're looking for is the SelectAll
typeclass. As to why the conversion doesn't kick in implicitly I'm not sure yet. It seems in the case that both the expected and the actual type are known like in your example the compiler has enough information to pick toOther
.
import shapeless._, ops.hlist.SelectAll
implicit def toOther[A <: HList, B <: HList](a: A)(implicit convert: SelectAll[A,B]): B = convert(a)
Upvotes: 3