组成不纯的功能

时间:2016-08-24 18:53:21

标签: javascript functional-programming ramda.js

假设我有以下不纯的功能:

// 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吗?是否有规范纯度和功能组成的规则?

1 个答案:

答案 0 :(得分:2)

首先,一个简化。您应该能够更简单地将createFooWithHighlights写为:

const createFooWithHighlights = R.compose(outlineFoo, createFoo);

现在回答真正的问题:

  

由于所有这些功能都会产生副作用,我应该避免使用R.compose吗?是否有规范纯度和功能组成的规则?

我会说不。函数式编程当然是关于减少副作用,将它们分流到程序的边缘,甚至可能将它们封装在模式和结构中(参见IO Monad的注释,这当然是很好的建议,但可能为时过早。)< / p>

但它不是关于消除副作用。一个完全没有副作用的程序只能计算一些硬编码输入的结果......然后不用费心去与你分享。

Ramda(免责声明:我是其中一位作者)严格避免副作用。但那是应该的。它是一个功能实用程序库;你不是其中一个决定你的程序如何与世界其他地方互动的人。或者至少我们在Ramda团队中没有。所以Ramda的功能是纯粹的。此外,Ramda旨在让您在实际操作中以简单的方式工作。

但这并不意味着它的函数应用于创建其他纯函数。当您需要创建副作用时,引入Ramda的工具完全没有问题,尤其是功能组合这样的重要工具。

所以你想要做的事情似乎完全符合Ramda的正常使用。