我已经掌握了一些有关函数式编程的知识,但实际上并不能完全围绕这个函数式编程代码进行研究。我真的不知道该在哪里问这样的问题,所以我在这里问了。因此,如果有人能帮助我了解这个高阶函数或一个monads的例子,我将不胜感激。
P.S该代码来自Eric Elliot撰写的软件书
const f = n => n+1;
const g = n => n*2;
此composeM
函数是为了组成和映射或映射多个函数?我知道reduce,但真的不知道该功能应该如何工作。
const composeM = (...mps) => mps.reduce((f, g) => x => g(x).map(f));
const h = composeM(f,g);
h(20)
然后,通过执行以下操作使函数composeM
更加通用化:
const compose = methods => (...mps) => mps.reduce((f, g) => x => g(x)[method](f));
然后,我可以像创建composedPromises
或composedMaps
const composePromises = compose("then")(f,g);
g(x)[method](f)
怎么工作?应该是g(x).then(f)
。
更新以上地图的composeM功能
const f = n => Promise.resolve( n+1 );
const g = n => Promise.resolve( n*2 );
const composePromises = (...mps) => mps.reduce((f, g) => x => g(x).then(f))
const h = composePromises(f, g)
h(20)
答案 0 :(得分:1)
考虑具有以下类型签名的函数组成。
// compose :: (b -> c) -- The 1st argument is a function from b to c.
// -> (a -> b) -- The 2nd argument is a function from a to b.
// -> (a -> c) -- The final result is a function from a to c.
// +-----------------b -> c
// | +---------a -> b
// | | +-- a
// | | |
const compose = (f, g) => x => f(g(x));
// |_____|
// |
// c
composeP
函数与compose
函数相似,不同之处在于它包含返回诺言的函数。
// composeP :: (b -> Promise c) -- The 1st argument is a function from b to promise of c.
// -> (a -> Promise b) -- The 2nd argument is a function from a to promise of b.
// -> (a -> Promise c) -- The final result is a function from a to promise of c.
// +-------------------------b -> Promise c
// | +-------- a -> Promise b
// | | +-- a
// | | |
const composeP = (f, g) => x => g(x).then(f);
// |__________|
// |
// Promise c
请记住,then
方法将回调函数应用于promise的值。如果我们将.then
替换为[method]
,其中method
是特定monad的bind函数的名称,那么我们可以组成产生该monad值的函数。
例如,.flatMap
是数组的绑定函数。因此,我们可以编写返回数组的函数,如下所示。
// composeA :: (b -> Array c) -- The 1st argument is a function from b to array of c.
// -> (a -> Array b) -- The 2nd argument is a function from a to array of b.
// -> (a -> Array c) -- The final result is a function from a to array of c.
const composeA = (f, g) => x => g(x).flatMap(f);
// f :: Bool -> Array String
const f = x => x ? ["yes"] : ["no"];
// g :: Int -> Array String
const g = n => [n <= 0, n >= 0];
// h :: Int -> Array String
const h = composeA(f, g);
console.log(h(-1)); // ["yes", "no"]
console.log(h(0)); // ["yes", "yes"]
console.log(h(1)); // ["no", "yes"]
那是一个非常人为的例子,但它说明了要点。
无论如何,通用compose
函数由monad组成。
const compose = method => (f, g) => x => g(x)[method](f);
const composeP = compose("then");
const composeA = compose("flatMap");
最后,各种monad compose
函数一次只能组成两个函数。我们可以使用reduce
一次组成其中的几个。希望有帮助。