0

我正在学习函数式编程,我刚刚读到了纯函数。

我的问题是:一个纯函数可以改变它的参数吗?

这个函数是纯的吗?

int a(Payment payment){
 payment.setValue(payment.getValue() - 1);
 return payment.getValue() * 10;
}
4

2 回答 2

3

这里有两件事:

  1. 纯函数是仅根据输入参数返回值的函数,调用该函数没有副作用

  2. 您粘贴的那段 Kotlin 代码无法编译(请参阅https://ideone.com/fli05T)。编译器说val cannot be reassigned。这是因为在 Kotlin 中,函数参数是不可变的。

理论上,如果可以按照您编写的那样定义这样的函数,那么根据(1)的定义,假设参数是按值传递的(在函数内部更改它们不会改变它们,如从函数外)。

于 2018-08-21T20:54:52.233 回答
1

规则是没有副作用。改变一个对象是一个副作用。然而,它并没有真正说你正在变异,所以这里是一个支付版本,你的代码是纯的:

public class Payment
{
  private int value;

  public Payment(int value) {
    this.value = value;
  }
  public Payment setValue(int value) {
    return new Payment(value);
  }
  public int getValue() {
    return value;
  }

  public static int a(Payment payment) {
      payment.setValue(payment.getValue() - 1); // dead code
      return payment.getValue() * 10;
  }

  public static int b(Payment payment) {
      return payment
        .setValue(payment.getValue() - 1)
        .getValue() * 10;
  }

  public static void main(String args[]) {
      Payment p = new Payment(10);
      System.out.println(String.valueOf(a(p)));
      System.out.println(String.valueOf(b(p)));
  }
}

请注意,您的定义a没有改变,它是 100% 功能的。如果你通过它,10它返回100,总是输入的 10 倍。然而,第一行返回一个新Payment的值9从来没有使用过,所以它是死代码。意图可能是我重写版本的意图,b. b也是功能性的。

现在其他的Payment可能实现ab不纯。

许多人认为 OO 和功能不能混合。Java 中最古老和最常用的类之一,java.lang.String既是面向对象的,又是纯函数式接口。没有方法发生变化,只返回一个新对象。

于 2018-08-21T21:59:53.917 回答