我想为管道创建一个撰写功能,但我被卡住了。我设法制作了一个无点管道,但无法弄清楚作曲。
// pointfree
const pipe = fn => future => future.pipe(fn)
// compose pipes // not working
const composePipe = (...fns) => (...args) => fns.reduceRight( (future, fn) => future.pipe(fn), args)[0];
我想为管道创建一个撰写功能,但我被卡住了。我设法制作了一个无点管道,但无法弄清楚作曲。
// pointfree
const pipe = fn => future => future.pipe(fn)
// compose pipes // not working
const composePipe = (...fns) => (...args) => fns.reduceRight( (future, fn) => future.pipe(fn), args)[0];
我最终会回答你的问题,但让我们先退后一步。
要理解的重要一点是 pipe 方法只是函数应用程序。换句话说:future.pipe (f) == f (future)
。
这意味着您的管道功能可以重新定义为:
const pipe = fn => future => future.pipe(fn)
//to:
const pipe = fn => value => fn (value)
这个新版本的管道的工作方式完全相同,除了它适用于任何值,而不仅仅是期货。但是,让我们更进一步。
该函数的签名如下:pipe :: (a -> b) -> a -> b
. 它接受一个从 A 到 B 的函数,并从 A 到 B 返回一个函数。
等一下....
const pipe = fn => value => fn (value)
//to:
const pipe = fn => fn
那个新定义做同样的事情。除了它适用于任何东西,而不仅仅是函数。实际上它只是身份功能。所以咖喱(你说的是无点,但我认为你的意思是咖喱)版本future.pipe
只是恒等函数。
那么这是为什么呢?因为所做.pipe
的只是功能应用。您可以自己应用您的功能。
现在回答您关于组成管道的下一个问题。您实际上正在寻找的是具有许多功能并按顺序应用它们的东西。
如果你使用 Ramda,那就是pipe
. 我们可以自己实现:
const pipe = (...fns) => (...args) => fns.reduce ((args, f) => [f (...args)], args)[0]