用于组成身份和副作用的函数式编程构造 [英] Functional programming construct for composing identity and side effect
问题描述
函数式编程是否具有这种逻辑的标准构造?
const passAround =(f)=> (x)=> {
f(x);
return x;
};
这使我可以编写具有副作用和无返回值的函数,如的console.log
。这不像一个任务,因为我不想代表副作用的状态。 SKI combinator calculus 可能会让你感兴趣。假设 f
总是一个纯函数:
const S = g => f => x => G(X)(F(X)); // SKI组合器calculusconst的S组合器K = x => y => X; // SKI combinator calculusconst的K combinator passAround = S(K); //是的,passAround函数只是SKconsole.log(passAround(console.log)(10)+ 20);
无论如何,我提出SKI combinator微积分的原因是因为我想向你介绍 Applicative Functors 。特别是, Reader
应用函数是等效 SKI组合演算。 S
组合子相当于读者和<$ c的方法#v:aprel =noreferrer> ap
$ c> K combinator相当于读者。
在JavaScript中,相当于 Reader
是 Function
。因此,我们可以为JavaScript中的函数定义 ap
和 pure
,如下所示:
Function.prototype.ap = function(f){return x => this(x)(f(x));}; Function.pure = x => y => x; const print = Function.pure.ap(console.log); console.log(print(10)+ 20);
但是请等待,您可以使用应用函子做更多的事情。每个应用函子也是一个函子。这意味着应用仿函数也必须具有 map
方法。对于读者
map
方法只是功能组合。它相当于 B
组合子。使用 map
您可以做一些非常有趣的事情,例如:
Function.prototype.ap = function(f){return x => this(x)(f(x));}; Function.pure = x => y => x; const id = x => X; //我组合SKI combinator calculusFunction.prototype.map = function(f){return x => this(f(x));}; Function.prototype.seq = function(g){return Function.pure(id).map(this).ap(g);}; const result = console.log.seq x => x + 20); console.log(result(10));
b $ b
seq
函数实际上等同于 (*>)
应用程序的方法类。这启用了方法级联的功能样式。
Does functional programming have a standard construct for this logic?
const passAround = (f) => (x) => {
f(x);
return x;
};
This enables me to compose functions that have side effects and no return values, like console.log
. It's not like a Task because I don't want to represent the state of the side effect.
The SKI combinator calculus might interest you. Let's pretend that f
is always a pure function:
const S = g => f => x => g(x)(f(x)); // S combinator of SKI combinator calculus
const K = x => y => x; // K combinator of SKI combinator calculus
const passAround = S(K); // Yes, the passAround function is just SK
console.log(passAround(console.log)(10) + 20);
Anyway, the reason why I bring up the SKI combinator calculus is because I want to introduce you to the concept of Applicative Functors. In particular, the Reader
applicative functor is equivalent to the SKI combinator calculus. The S
combinator is equivalent to the ap
method of Reader
and the K
combinator is equivalent to the pure
method of Reader
.
In JavaScript, the equivalent of Reader
is Function
. Hence, we can define ap
and pure
for functions in JavaScript as follows:
Function.prototype.ap = function (f) {
return x => this(x)(f(x));
};
Function.pure = x => y => x;
const print = Function.pure.ap(console.log);
console.log(print(10) + 20);
But wait, there's so much more that you can do with applicative functors. Every applicative functor is also a functor. This means that applicative functors must also have a map
method. For Reader
the map
method is just function composition. It's equivalent to the B
combinator. Using map
you can do really interesting things like:
Function.prototype.ap = function (f) {
return x => this(x)(f(x));
};
Function.pure = x => y => x;
const id = x => x; // I combinator of SKI combinator calculus
Function.prototype.map = function (f) {
return x => this(f(x));
};
Function.prototype.seq = function (g) {
return Function.pure(id).map(this).ap(g);
};
const result = console.log.seq(x => x + 20);
console.log(result(10));
The seq
function is in fact equivalent to the (*>)
method of the Applicative class. This enables a functional style of method cascading.
这篇关于用于组成身份和副作用的函数式编程构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!