什么时候使用Monad?
  • 具有静态的IO方法和join方法的函子
  • 当一个函数返回一个函子的时候,我们就要想到monad,monad可以帮我们解决函子嵌套的问题。
  • 当我们想要返回一个函数,这个函数返回一个值,这个时候可以调用map 方法
  • 当我们想要去合并一个函数,但是这个函数返回一个函子,这个时候我们要用flatMap 方法
  1. 示例: ```javascript const fp = require(‘lodash/fp’) const fs = require(‘fs’)

class IO { static of (value) { return new IO(() => { return value }) } constructor (fn) { this._value = fn }

map(fn) { return new IO(fp.flowRight(fn, this._value)) } }

//读取文件函数 let readFile = (filename) => { return new IO(() => { //同步获取文件 return fs.readFileSync(filename, ‘utf-8’) }) }

//打印函数 // x是上一步的IO函子 let print = (x) => { return new IO(()=> { console.log(x) return x }) }

// 组合函数,先读文件再打印 let cat = fp.flowRight(print, readFile) // 调用 // 拿到的结果是嵌套的IO函子 IO(IO(x)) let r = cat(‘package.json’) console.log(r) // IO { _value: [Function] } console.log(cat(‘package.json’)._value()) // IO { _value: [Function] } // IO { _value: [Function] } console.log(cat(‘package.json’)._value()._value()) // IO { _value: [Function] }

  1. 2. 实现一个Monad函子:
  2. ```javascript
  3. const fp = require('lodash/fp')
  4. const fs = require('fs')
  5. class IO {
  6. static of (value) {
  7. return new IO(() => {
  8. return value
  9. })
  10. }
  11. constructor (fn) {
  12. this._value = fn
  13. }
  14. map(fn) {
  15. return new IO(fp.flowRight(fn, this._value))
  16. }
  17. join () {
  18. return this._value()
  19. }
  20. // 同时调用map和join方法
  21. flatMap (fn) {
  22. return this.map(fn).join()
  23. }
  24. }
  25. let readFile = (filename) => {
  26. return new IO(() => {
  27. return fs.readFileSync(filename, 'utf-8')
  28. })
  29. }
  30. let print = (x) => {
  31. return new IO(()=> {
  32. console.log(x)
  33. return x
  34. })
  35. }
  36. let r = readFile('package.json')
  37. .flatMap(print)
  38. .join()
  39. // 执行顺序
  40. /**
  41. * readFile读取了文件,然后返回了一个IO函子
  42. * 调用flatMap是用readFile返回的IO函子调用的
  43. * 并且传入了一个print函数参数
  44. * 调用flatMap的时候,内部先调用map,当前的print和this._value进行合并,合并之后返回了一个新的函子
  45. * (this._value就是readFile返回IO函子的函数:
  46. * () => {
  47. return fs.readFileSync(filename, 'utf-8')
  48. }
  49. * )
  50. * flatMap中的map函数执行完,print函数返回的一个IO函子,里面包裹的还是一个IO函子
  51. * 下面调用join函数,join函数就是调用返回的新函子内部的this._value()函数
  52. * 这个this._value就是之前print和this._value的组合函数,调用之后返回的就是print的返回结果
  53. * 所以flatMap执行完毕之后,返回的就是print函数返回的IO函子
  54. * */
  55. r = readFile('package.json')
  56. // 处理数据,直接在读取文件之后,使用map进行处理即可
  57. .map(fp.toUpper)
  58. .flatMap(print)
  59. .join()
  60. // 读完文件之后想要处理数据,怎么办?
  61. // 直接在读取文件之后调用map方法即可