假设我有以下不纯的功能:
// Mounts a foo instance into the given dom node
// (this is an implementation detail of the Foo library),
// then returns the foo instance.
const createFoo = (FooConstructor, domNode, options) => {
return new FooConstructor(domNode, options);
};
const outlineFoo = foo => {
foo.getCanvas().outline = true;
return foo;
}
如果我想使用R.compose
创建Foo实例并突出显示它,我可以编写一个函数:
const createFooWithHighlights = (FooConstructor, domNode, options) => {
return R.compose(
outlineFoo,
createFoo
)(FooConstructor, domNode, options)
}
如果我想使用命令式编程来完成同样的事情,我会这样做:
const createFooWithHighlights = (FooConstructor, domNode, options) => {
const foo = createFoo(FooConstructor, domNode, options);
outlineFoo(foo);
return foo;
}
无论我们选择哪一个,它都会被调用:
const highlightedFooInDOM = createFooWithHighlights(Foo, document.body, {})
由于所有这些功能都会产生副作用,我应该避免使用R.compose
吗?是否有规范纯度和功能组成的规则?
答案 0 :(得分:2)
首先,一个简化。您应该能够更简单地将createFooWithHighlights
写为:
const createFooWithHighlights = R.compose(outlineFoo, createFoo);
现在回答真正的问题:
由于所有这些功能都会产生副作用,我应该避免使用
R.compose
吗?是否有规范纯度和功能组成的规则?
我会说不。函数式编程当然是关于减少副作用,将它们分流到程序的边缘,甚至可能将它们封装在模式和结构中(参见IO Monad的注释,这当然是很好的建议,但可能为时过早。)< / p>
但它不是关于消除副作用。一个完全没有副作用的程序只能计算一些硬编码输入的结果......然后不用费心去与你分享。
Ramda(免责声明:我是其中一位作者)严格避免副作用。但那是应该的。它是一个功能实用程序库;你不是其中一个决定你的程序如何与世界其他地方互动的人。或者至少我们在Ramda团队中没有。所以Ramda的功能是纯粹的。此外,Ramda旨在让您在实际操作中以简单的方式工作。
但这并不意味着它的函数应仅用于创建其他纯函数。当您需要创建副作用时,引入Ramda的工具完全没有问题,尤其是功能组合这样的重要工具。
所以你想要做的事情似乎完全符合Ramda的正常使用。