For simplicity sake let's assume my HList
instance holds exactly 2 values:
def intToString(x: Int) = x + "_"
def intToDouble(x: Int) = x * 10d
val fns = (intToString _ :: intToDouble _ :: HNil)
Now I'd like, having some Hlist
of ints, to be able to do this:
(fns zip (1 :: 2 :: HList) map {case (f, x) => f(x) }
to get
("1_", 10.0)
From now on, assume that I don't know what I am doing and I totally understand all my paltriness in the faces of the functional gods.
I already looked at shapeless' wiki and, as far as I understood, I should make a function from Int
to T
that can be accepted by shapeless. Did I understood correct? Here's what I got:
object mapApply extends Poly1 {
implicit def default[T] = at[Function[Int,T]](f => f.apply _)
}
At this point I'm completely lost and don't even have a clue of how to proceed. But I'm kinda fascinated by the potential power and expressiveness that this could deliver, so I'd really like to understand how this stuff works. I would really appreciate if your answers will not be just code snippets but rather more open and explanatory.
P.S. SO's engine just suggested me a c++
tag. Did I say something C++-ish?
It looks like you're mixing method and function definition syntax—I'll assume you meant something like the following:
val intToString = (x: Int) => x + "_"
val intToDouble = (x: Int) => x * 10d
val fns = intToString :: intToDouble :: HNil
Now you can use zipApply
, which just pairs functions and their arguments:
val res = fns.zipApply(1 :: 2 :: HNil)
If for some reason zipApply
didn't exist, you could accomplish the same thing with a Poly1
:
object apply extends Poly1 {
implicit def default[I, O]: Case.Aux[(I => O, I), O] =
at[(I => O, I)] { case (f, x) => f(x) }
}
val res = fns.zip(1 :: 2 :: HNil).map(apply)
Or this, if you don't want the extra genericity:
object applyToInt extends Poly1 {
implicit def default[T]: Case.Aux[(Int => T, Int), T] =
at[(Int => T, Int)] { case (f, x) => f(x) }
}
So you weren't too far off—you just needed to have a case in your Poly1
for the pair of the function and the argument, not just the function.