【响应式编程的思维艺术】 (3)flatMap背后的代数理论Monad (2)

现在来实现这样一个功能,读入一个文件的内容,将其中的a字符全部换成b字符,接着存入另一个文件,完成后在控制台输出一个消息,为了更明显地看到数据容器的作用,我们使用同步方法并将其包裹在IO容器中,然后利用函数式编程:

var fs = require('fs'); //读取文件 var readFile = (filename)=>IO.of(fs.readFileSync(filename,'utf-8')); //转换字符 var transContent = (content)=>IO.of((content)=>content.replace('a','b')); //写入字符串 var writeFile = (content)=>IO.of(fs.writeFileSync('dest.txt',content));

当具体的函数被IO容器包裹起来而实现延迟执行的效果时,就无法按原来的方式使用compose( )运算符直接对功能进行组合,因为readFile函数运行时的输出结果(一个io容器实例)和transContent函数需要的参数类型(字符串)不再匹配,在不修改原有函数定义的前提下,函数式编程中采用的做法是使用map操作符来预置一个参数:

/* *map(transContent)是一个高阶函数,它的返回函数就可以接收一个容器实例, *并对容器中的内容执行map操作。 */ var taskStep12 = compose(map(transContent), readFile);

这里比较晦涩,涉及到很多功能性函数的嵌套,建议手动推导一下taskStep12这个变量的值,它的结构是这样一种形式:

io{ __value:io{ __value:someComposedFnExpression } }

如果试图一次性将所有的步骤组合在一起,就需要采用下面的形式:

var task = compose(map(map(writeFile)),map(transContent),readFile); //组合后的task形式就是 //io{io{io{__value:someComposedFnExpression}}}

问题已经浮出水面了,每多加一个针对容器操作的步骤,书写时就需要多包裹一层map,而运行时就需要多进入一层才能触及组合好的可以实现真正功能的函数表达式,真的是很麻烦。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygjdw.html