含义:

    1. 是一个可以拍扁的pointed函子, 即有of静态方法, 还可以解决函子嵌套的问题 ```javascript const fs = require(“fs”); const { flowRight, toUpper } = require(“lodash/fp”);

    class IO { static of(value) { return new IO(value); } constructor(value) { this._value = value; } map(fn) { /**

    1. * this._value => readFile被调用返回的函子 new IO(() => { return fs.readFileSync(filename, "utf-8");})
    2. * fn => 是通过调用flatMap方法传递进来的 print 即(value) => { return new IO(() => { console.log("value", value); return value; })}
    3. * flowRight(fn, this._value)的组合函数 => 复制 this._value
    4. * return new IO(flowRight(fn, this._value)) => 最终返回一个新的函子
    5. */
    6. return new IO(flowRight(fn, this._value));

    } join() { /**

     * 调用this._value() => 其实是调用 flowRight(fn, this._value) 这个组合函数
     * 
     */
    return this._value(); // 返回一个函子
    

    } flatMap(fn) { // flatMap return this.map(fn).join(); } }

    // readFile 是一个读取文件的方法,然而读取文件是一个不纯的操作,因此将不纯的行为封装到IO函子中,通过延迟执行函数,控制不纯的行为 const readFile = (filename) => { return new IO(() => { return fs.readFileSync(filename, “utf-8”); }); };

    // print 是一个读取文件的方法,然而读取文件是一个不纯的操作,因此将不纯的行为封装到IO函子中,通过延迟执行函数,控制不纯的行为 const print = (value) => { return new IO(() => { console.log(“value”, value); // 这个值 最终指向 readFile 返回的函子执行的结果,即文件目录的内容 return value; }); };

    // readFile返回函子, print返回函子,IO(IO(X)) // const v = flowRight(print, readFile); // const r = v(“package.json”)._value()._value(); // console.log(r);

    let r = readFile(“package.json”).map(toUpper).flatMap(print).join(); console.log(r)

    ```