何时使用部分应用函数

15

注意:如果你只是想跳过上下文,请直接跳到下面的"问题"。

在讲述Scala时,我通常会讲解以下类似的“玩具问题”作为部分应用函数的示例。

def multiply(x:Int, y:Int): Int = x * y
val x5 = multiply(5, _:Int)
x5(10) //produces 50

这个例子确实有帮助,但对于我来说很难解释何时应该使用部分应用函数的一般性概念。

问题: 有没有人有自己成功解释部分应用函数的方法,特别是对于Java(或其他面向对象语言)开发人员?

3个回答

25

假设你想要应用销售税。

def withTax(cost: Float, state: String) = { /* Some complicated lookup table */ }

假设现在你想在纽约购买一大堆东西。

val locallyTaxed = withTax(_: Float, "NY")
val costOfApples = locallyTaxed(price("apples"))

通过不必指定在本地始终相同的参数,您可以从原始方法获得最大的代码重用,同时对于重复任务具有最大的便利性。

人们常常试图使用隐式解决这个问题:

def withTax(cost: Float)(implicit val state: String) = ...

不要这样做!(除非经过仔细考虑。)很难追踪在某个时间点哪个隐式值在周围存在。使用部分应用函数,您可以获得相同的输入节省,并且每次使用时键入名称,因此您知道正在使用哪个函数!


啊,我可以看到这真的会减少你需要定义的“过载”函数的数量。谢谢。 - ThaDon
我刚刚读完了部分应用函数,并想知道在什么可能的情况下我会使用它,这里就是答案...对于出色的解释加一分。 - Sikorski

8

在Java中,您经常将部分应用函数的第一个(或更多)参数传递给类的构造函数。Rex的示例可能如下所示:

class TaxProvider {
    final String state;

    TaxProvider(String state) {
        this.state = state;
    }

    double getTaxedCost(double cost) {
      return ... // look up tax for state and apply to cost
    }
}


TaxProvider locallyTaxed = new TaxProvider("NY")
double costOfApples = locallyTaxed.getTaxedCost(price("apples"))

2

我想Scala具有函数组合的功能,这是部分应用函数发挥优势的地方。

另一个点是高阶函数,比如像filter这样的函数,它接受一个谓词参数,并且可以像这样使用:

filter (<42) list  -- sorry, don't speak Scala

谓词通常是一些部分应用的函数。同样适用于mapfold等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接