提问人:Isaac 提问时间:9/20/2021 更新时间:9/21/2021 访问量:95
如果我们使用闭包,如何提高功能的纯度
How to enhance purity of function if we are using closures
问:
我有一个伪函数,如下所示
let counter = 0;
function createNewFile() {
const fileName = `book_${counter++}`;
//...write file or whatever
};
上述功能绝对不理想,因为它依赖于外部变量,可能会意外更改。我正在考虑通过关闭和 IIFE 来减少这种情况发生的可能性,如下所示createNewFile
counter
const counter = (() => {
let counter = 0;
return () => counter++;
})();
console.log(counter())
console.log(counter())
/*
function createNewFile() {
const fileName = `book_${counter()}`;
//...write file or whatever
};
*/
上面的代码达到了现在可以说“更难”“意外”更改的目的。counter
但是,我想知道从函数式编程的角度来看,我们如何才能同时改进函数和?因为显然两者都违反了规则,而且两个函数在每次执行时都不提供相同的输出,所以我很好奇如何在给定用例的情况下增强代码?counter
createNewFile
pure function
答:
1赞
user5536315
9/21/2021
#1
您的函数与两个效果有关:
- 依赖局部变量进行突变
- 通过写入文件系统进行 I/O
您可以通过将局部变量作为参数传递来简单地避免局部变量。状态将移动到调用堆栈。但是,使用这种技术无法避免所有突变。出于这个原因,函数式编程通常提供持久数据结构,这是一种巧妙的不变形式。
I/O 效果更难处理。在 Javascript 中,I/O 通常是异步的,因此 promise 用于对此类计算进行编码。不幸的是,从功能角度来看,promise 具有相当无原则的语义,因此我将使用原始延续类型来展示如何在后台延迟 I/O 效果:
function createNewFile(counter, data) {
const fileName = `book_${counter}`;
return k => {run: k(writeFile(fileName, data))}
};
const description = createNewFile(1, someData);
description.run(checkSuccess);
我们没有执行效果,而只是得到这个动作的描述。该函数本身并不是特别有用。我们需要方法将其结果应用于其他纯函数,或者将其与其他描述相结合,而无需实际执行效果,但这超出了本答案的范围。
评论
function createNewFile(counterValue) { /* ... */ }
createNewFile(counter);
counter
createNewFile