Created
March 24, 2012 22:24
-
-
Save mergeconflict/2188596 to your computer and use it in GitHub Desktop.
packaging and unpackaging multiple implicit conversions in an HList
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
object AllExamples extends App { | |
import shapeless._ | |
final class All[L <: HList](val values: L) { | |
def apply[A](implicit selector: Selector[L, A]): A = values.select[A] | |
} | |
object All { | |
// package a value of type A, convertible to type B, into an HList containing just B | |
implicit def toAll0[A, B](a: A)(implicit a2b: A => B): All[B :: HNil] = | |
new All(a :: HNil) | |
// package a value of type A, convertible to B and some other types L, into an HList containing B and all types in L | |
implicit def toAll1[A, B, L <: _ :: _](a: A)(implicit a2b: A => B, a2l: A => All[L]): All[B :: L] = | |
new All(a :: a.values) | |
} | |
// example data | |
trait A { def a: String } | |
trait B { def b: String } | |
trait C { def c: String } | |
implicit def intA(n: Int): A = new A { def a = "a " + n.toString } | |
implicit def intB(n: Int): B = new B { def b = "b " + n.toString } | |
implicit def intC(n: Int): C = new C { def c = "c " + n.toString } | |
implicit def stringA(s: String): A = new A { def a = "a " + s } | |
implicit def stringB(s: String): B = new B { def b = "b " + s } | |
implicit def stringC(s: String): C = new C { def c = "c " + s } | |
// implicitly convert int and string values to A, B and Cs | |
val abcs: Seq[All[A :: B :: C :: HNil]] = Seq(1, "haha", 2, "hoho") | |
// unpack | |
for (abc <- abcs) { | |
println(abc[A].a) | |
println(abc[B].b) | |
println(abc[C].c) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, exactly that. Sorry I confused things by mentioning conversions ... I was playing around with something which tried to use a conversion from All[... T ...] to T which got bitten by exactly the same problem.
In my Pack case things are a bit different: the additional structure in the result type (due to the outer type constructor) seems to be enough to allow the inference/resolution to go through. I think having a single argument list with multiple Packs at different type constructors will probably work, but I haven't checked.