shayan
shayan

Reputation: 1241

implicit conversion of one HList to another

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

Answers (1)

Jasper-M
Jasper-M

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

Related Questions