如何使用IO monad正确创建DOM元素?

时间:2019-03-26 13:19:47

标签: javascript functional-programming monads

我正在尝试编写一个生成DOM元素的JavaScript代码,但是以一种功能性的方式进行,因为所有功能都会产生副作用和变异。为此,我使用了IO monad,但是我仍然不知道如何很好地使用它们...

首先,我正在使用crocks库,该库提供了许多与功能性JS配合使用的ADT(我知道有ramda,但它们不提供monad)。另外,我正在使用一个小模块,该模块允许我使用合成来声明DOM元素。 (https://github.com/queckezz/elementx

>>> foo = [1,2]
>>> bar = [3,4]
>>> result = foo.extend(bar)
>>> print foo
[1, 2, 3, 4]
>>> print bar
[3, 4]
>>> print result
None

上面的代码有效,但是显然不纯。我保留了导入的IO,但是我没有使用它,因为我不知道如何在不破坏代码的情况下实现。我知道IO必须接收一个函数作为参数,然后它返回IO(f(x)),但是我对于如何将其同时实现到createHeader变量和appendChild都一无所知。此外,对于IO,当我运行它时,createHeader变量返回一个函数,但是appendChild需要一个Node对象。

1 个答案:

答案 0 :(得分:1)

好的,所以我解决了这个问题,主要问题是...我正在将一个不会产生副作用(如果不附加到DOM上,createHeader不会做任何事情)的函数视为不纯。 igh ...新手,我。

如bob在评论中所说,唯一不纯的部分是附加。

所以我的解决方法是:

//append might not be a good name for this action but...
const append = nodeObj => IO(() => {
  document.body.appendChild(nodeObj);
})

append(createHeader)
  .run();

仅在IO被“激活”后才创建DOM元素,从而推迟了副作用。希望这对其他新手函数程序员有所帮助!