我正在尝试编写一段生成DOM元素的javascript代码,但它是以函数的方式实现的,因为所有函数都会产生副作用和突变。为了实现这一点,我正在使用IO monad,但我想我仍然不知道如何很好地使用它们……
首先,我使用了crocks库,它提供了大量的ADT来处理函数式JS (我知道有ramda,但他们不提供monad)。另外,我还使用了一个小模块,它允许我使用组合来声明DOM元素。(https://github.com/queckezz/elementx)
import IO from 'crocks/IO';
const { div, a, h1, h2, ul, li, button } = require('elementx');
const createHeader = div(
h1(
{class: 'title'},
'This is a title'
),
h2(
{class: 'subtitle'},
'This is a subtitle'
),
div(
{class: 'link'},
a(
{href: 'http://github.com'},
'Github'
)
)
);
document.body.appendChild(createHeader);上面的代码可以工作,但它显然是不纯的。我导入了IO,但我没有使用它,因为我不知道如何在不破坏代码的情况下实现它。我知道IO必须接收一个函数作为参数,然后返回IO(f(x)),但是我完全不知道如何在createHeader变量和appendChild中实现它。此外,对于IO,当我运行createHeader变量时,它会返回一个函数,但appendChild需要一个Node对象。
发布于 2019-03-26 22:54:13
好了,我解决了这个问题,主要的问题是……我把一个没有产生副作用的函数(如果不附加到DOM中,createHeader什么都不会做)视为不纯的。Sigh...newbie me。
正如bob在评论中所说的,唯一不纯的部分是append。
因此,我的解决方案如下:
//append might not be a good name for this action but...
const append = nodeObj => IO(() => {
document.body.appendChild(nodeObj);
})
append(createHeader)
.run();它只在IO被“激活”时创建DOM元素,因此推迟了副作用。希望这对其他函数式编程新手有所帮助!
https://stackoverflow.com/questions/55358197
复制相似问题