任意函数都有一个Wrapper类。我试图用两个类型参数[I,O](用于输入和输出)抽象函数的输入和输出(返回值)。
class Wrapper[I, O](protected val f: I => O {
protected def doIt(input: I): O = f(input)
}
因为这应该是任意函数的包装器,所以我遇到了带有多个参数的函数的问题。
val multiplyFunction = (a: Int, b: Int) => a * b
val multiplyWrapper = new Wrapper[(Int, Int), Int](multiplyFunction)
第二行不编译,因为包装器需要一个函数,它将一个带有两个Int的元组作为唯一参数。
有没有办法重写这个,所以我可以抽象函数的参数,无论有多少参数?理想情况下,编译器的解决方案是类型安全的。
也许我在创建实例时可以使用元组来指定包装器的类型。
我希望我没有像Tuple classe Tuple2到TupleN或Function2到FunctionN那样写它。我不知道有关这方面的所有细节,但这看起来更像是一种解决方法,而不是一个抽象/通用的解决方案。
答案 0 :(得分:3)
您可以在功能上使用tupled
方法:new Wrapper(multiplyFunction.tupled)
。
如果你想让包装类的用户透明,你可以使用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
由于反思,你会得到一些开销。