gpt4 book ai didi

javascript - 可以使用 hof/compose/currying/partial application/monads 将此代码重构为更具功能性的编程风格吗?

转载 作者:太空宇宙 更新时间:2023-11-04 15:56:17 25 4
gpt4 key购买 nike

我刚刚开始学习函数式编程,并且正在尝试将所学知识付诸实践。我有下面的代码,我只是不知道在哪里可以应用函数组合,在这个函数中部分应用。

有什么想法如何使用函数技术重构它吗?

function compareCodes(validateFn, moreProcessingFn, doStuffOnCodeAFn, doStuffOnCodeBFn, doSomething1Fn, doSomething2Fn, codeA, codeB, param1, param2) {

let result = null;
if (validateFn(codeA, codeB)) {
const isCodeAValid = doStuffOnCodeAFn(codeA); // returns a boolean
const isCodeBValid = doStuffOnCodeBFn(codeB); // returns a boolean
const isItAMatch = moreProcessingFn(isCodeAValid, isCodeBValid, codeA, codeB); // returns a boolean
if (isItAMatch) {
result = doSomething1Fn (param1, param2);
} else {
result = doSomething2Fn (param1, param2);
}
}
return result;
}

最佳答案

第一步是删除所有辅助变量。虽然 bool 中间变量通过其描述性名称易于理解,但至少 result 是完全不必要的。

function compareCodes(validateFn, moreProcessingFn, doStuffOnCodeAFn, doStuffOnCodeBFn, doSomething1Fn, doSomething2Fn, codeA, codeB, param1, param2) {
return validateFn(codeA, codeB)
? (moreProcessingFn(doStuffOnCodeAFn(codeA), doStuffOnCodeBFn(codeB), codeA, codeB)
? doSomething1Fn
: doSomething2Fn
)(param1, param2)
: null;
}

接下来,您可以应用一些柯里化(Currying)(您可以对每个参数执行此操作,但我认为它在可能一起使用的 block 中更有用):

function compareCodes(validateFn, moreProcessingFn, doStuffOnCodeAFn, doStuffOnCodeBFn, doSomething1Fn, doSomething2Fn) {
return function(codeA, codeB) {
return validateFn(codeA, codeB)
? moreProcessingFn(doStuffOnCodeAFn(codeA), doStuffOnCodeBFn(codeB), codeA, codeB)
? doSomething1Fn
: doSomething2Fn
: function(param1, param2) { return null; };
};
}

但仅此而已。虽然可以为条件编写自己的组合器并将多个参数并行输入到多个函数中,但在此过程中您不会获得任何好处。当然没有像组合这样的标准组合器可以帮助您。

如果您不再总是一起提供两个东西(A 和 B、1 和 2)但作为不同的参数,情况可能会有所不同。如果您修改所有函数以采用元组(此处表示为长度为 2 的数组,因为 JavaScript 缺乏对类型),我们可以做一些事情。首先我们转换自

function compareCodes(validateFn, moreProcessingFn, [doStuffOnCodeAFn, doStuffOnCodeBFn], [doSomething1Fn, doSomething2Fn], [codeA, codeB], [param1, param2]) {
return validateFn([codeA, codeB])
? (moreProcessingFn([doStuffOnCodeAFn(codeA), doStuffOnCodeBFn(codeB)], [codeA, codeB])
? doSomething1Fn
: doSomething2Fn
)([param1, param2])
: null;
}

to(我使用的是 ES6 语法,值得注意的箭头函数和解构)

const bimap = ([f, g]) => ([x, y]) => [f(x), g(y)];
const fst = ([x, _]) => x;
const snd = ([_, y]) => y;

function compareCodes(validate, moreProcessing, doStuff, doSomething, code, param) {
return validate(code)
? (moreProcessing(bimap(doStuff)(code), code)
? fst
: snd
)(doSomething)(param)
: null;
}

现在我们确实可以用组合器来解决这个问题:

const compose = f => g => x => f(g(x));
const bind = f => g => x => f(g(x), x);
const cond = pred => then => other => x => pred(x) ? then(x) : other(x);
const k = x => _ => x;


function compareCodes(validate, moreProcessing, doStuff, doSomething)
return cond(validate,
cond(bind(moreProcessing)(compose(bimap)(doStuff)),
fst(doSomething),
snd(doSomething)
),
k(k(null))
);
}

我们可以进一步对 compareCodes 进行完全无点的定义,但老实说,这不值得。

关于javascript - 可以使用 hof/compose/currying/partial application/monads 将此代码重构为更具功能性的编程风格吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42660594/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com