这可以被认为是一个纯函数(函数式编程)吗?

thi*_*goh 5 paradigms functional-programming purely-functional

我一直在阅读函数式编程及其概念.我很清楚,在大项目中工作时,你总是需要混合(在某种程度上)多种范例,如OO和功能.从理论上讲,功能纯度等概念太严格了

在给定相同参数值的情况下,该函数始终评估相同的结果值.函数结果值不能取决于程序执行过程中或程序的不同执行之间可能发生变化的任何隐藏信息或状态,也不依赖于I/O设备的任何外部输入.(https://en.wikipedia.org/wiki/Pure_function)

那就是说,这个(或者可以认为)代码是一个纯函数吗?

const externalVar = 10;

function timesTen(value) {
    return externalVar * value;
}
Run Code Online (Sandbox Code Playgroud)

我问这个是因为,在这种情况下,timesTen函数将始终为输入返回相同的值,任何人都可以更改值,externalVar因为这是一个常量.但是,此代码违反了访问外部函数范围的规则.

Syl*_*ter 5

是.它保证是纯净的.

原因是它只依赖于绑定和不可变的自由变量.

但是,此代码违反了访问外部函数范围的规则.

您的引言中没有任何内容表明您无法访问自由变量.它表示外部输入是从文件,网络等读取而不是来自先前范​​围的自由变量.

即使Haskell也使用全局函数名称foldr,它在使用的每个函数中都是一个自由变量,当然结果是纯粹的.

请记住,按名称的函数只是变量.parseInt是一个指向函数的变量,因此如果要在另一个函数中使用的每个函数都作为参数传递,那么根本不需要做任何事情.

如果你重新定义parseInt了一些非纯粹的东西或者在程序的持续时间内,它的工作方式不同,那么调用它的函数就不会是纯粹的.

功能组合和部分评估工作因为它们提供自由变量.它是函数式编程中一种必不可少的抽象方法.例如.

function compose(f2, f1) {
  return (...args) => f2(f1(...args));
}

function makeAdder(initialValue) {
  return v => v + initialValue;
}

const add11 = compose(makeAdder(10), makeAdder(1));
add11(5); // ==> 16
Run Code Online (Sandbox Code Playgroud)

这很纯粹.封闭的可变/自由变量f1,f2,initialValue从来没有为创建的功能变化.add11是一个纯粹的功能.

现在compose再看一遍.它看起来很纯净但可能会受到污染.如果不是两个函数都传递给它是纯粹的,结果也不是.

OO也可以是纯粹的功能!

通过不改变您创建的对象,可以轻松地组合它们.

class FunctionalNumber {
  constructor(value) {
    this.value = value;
  }
  add(fn) {
    return new FunctionalNumber(this.value + fn.value);
  }
  sub(fn) {
    return new FunctionalNumber(this.value - fn.value);
  }        
}
Run Code Online (Sandbox Code Playgroud)

这个课程纯粹是功能性的.

实际上,您可以将方法调用obj.someMethod(arg1, arg2)视为具有obj第一个参数的函数调用someFunction(obj, arg1, arg2).它只是语法上的差异,如果someFunction发生变异,obj你会说它不纯粹.这是它是如何与someMethodobj太.

您可以创建适用于大型数据结构的类,这意味着您在执行回溯拼图求解器时更改之前无需复制它.一个简单的例子是Haskell和Lisp中的对.这是在JavaScript中实现它的一种方法:

class Cons {
  constructor(car, cdr) {
    this.car = car;
    this.cdr = cdr;
  }
}

const lst = new Cons(1, new Cons(2, new Cons(3, null)));
const lst0 = new Cons(0, lst);
Run Code Online (Sandbox Code Playgroud)

lst0lst,但在前面的新元素.lst0重用一切lst.从列表到二叉树的所有内容都可以用这个来创建,你可以用不可变的二叉树创建许多顺序数据结构.它自50年代以来一直存在.