Question

There is a Wrapper class for arbitrary functions. I tried to abstract the input and output (return value) of the function with the two type parameters [I, O] (for input and output).

class Wrapper[I, O](protected val f: I => O {

    protected def doIt(input: I): O = f(input)

}

As this should be a wrapper for arbitrary functions, I have a problem with functions that take multiple parameters.

val multiplyFunction = (a: Int, b: Int) => a * b
val multiplyWrapper = new Wrapper[(Int, Int), Int](multiplyFunction)

The second line does not compile, because the wrapper expects a function which takes a Tuple with two Ints as the only parameter.

Is there a way to rewrite this, so that I can abstract the function's parameters no matter how many parameters there are? Ideally the solution would be type safe, by the compiler.

Maybe I there is an alternative to using a tuple to specify the types for the wrapper when creating an instance it.

I hope I don't have to write it like the Tuple classe Tuple2 to TupleN or Function2 to FunctionN. I don't know all the details about this, but that does look more like a workaround and is not a abstract / generic solution.

Was it helpful?

Solution

You could use tupled method on function: new Wrapper(multiplyFunction.tupled).

If you want to make this transparent to the wrapper class's user you could use duck typing:

object Wrapper {
  def apply[I, O](e: { def tupled: I => O }) = new Wrapper(e.tupled)
  def apply[I, O](e: I => O) = new Wrapper(e)
}

scala> Wrapper( (a: Int) => a )
res0: Wrapper[Int,Int] = Wrapper@29d03e78

scala> Wrapper( (a: Int, b: Int) => a * b )
res1: Wrapper[(Int, Int),Int] = Wrapper@581cdfc2

You'll get some overhead due to reflection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top