Starting with Travis's answer, I was able to improve it:
In the first file I have:
package p2; import shapeless._, ops.record.Selector, record._, syntax.singleton._ object MyFields { type wfoo1[L<: HList]=Selector.Aux[L,Witness.`"foo1"`.T, String] type wfoo2[L<: HList]=Selector.Aux[L,Witness.`"foo2"`.T, Int] }
and then, in another place:
package p1; import shapeless._, ops.record.Selector, record._, syntax.singleton._ import p2.MyFields._ object testshapeless extends App { def fun1[L <: HList](l: L)(implicit foo1: wfoo1[L], foo2: wfoo2[L] ): (String, Double) = (foo1(l), foo2(l)) val rec = ("foo1" ->> "hello") :: ("foo2" ->> 1) :: ("foo3" ->> 1.2) :: HNil println(fun1(rec)); }
The first file can be thought of as a scheme where I declare fields that I can potentially use in my application, and I just want to import them.
That's cool!
Edited June 30: I wonder if we can do better, maybe with a macro: Can I write something like:
def fun1[L <:HList] WithSelectors(MyFields)=...
The WithSelectors macro will generate:
(implicit foo1: wfoo1[L], foo2: wfoo2[L] )
Any tips?
source share