纯函数可以更改输入值吗?

时间:2018-08-21 20:48:44

标签: java functional-programming pure-function

我正在研究函数式编程,我刚刚读了有关Pure函数的信息。

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

此功能是否纯净?

df=pd.DataFrame()
l=[{'id':234,'2018-01':2},
{'id':534,'2018-01':5},
{'id':534,'2018-03':4}]

for x in l:
    df=df.append(pd.Series(x).to_frame().T.set_index('id')).groupby(level=0).first()
    print(df)

     2018-01
id          
234        2
     2018-01
id          
234        2
534        5
     2018-01  2018-03
id                   
234      2.0      NaN
534      5.0      4.0

2 个答案:

答案 0 :(得分:3)

这里有两件事:

  1. 纯函数是具有返回值的函数,该返回值仅基于其输入参数,并且调用该函数具有没有副作用

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

理论上,如果可以定义您编写的函数,则根据(1)的定义,假设参数是通过值传递的(在函数内部更改它们不会更改它们),那将是纯粹的从函数外部看)。

答案 1 :(得分:1)

规则没有副作用。突变对象是一种副作用。但是,它并没有真正表明您正在变异,因此这是您的代码纯净的Payment版本:

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既是面向对象的,又是纯功能的接口。没有方法会发生变化,只会返回一个新对象。