【前端进阶】IO函子

570 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」     ,赢取创作大礼包,挑战创作激励金

IO函子

前言

我们在之前的文章中已经学过了好几个函子了

IO函子和之前的函子不同的地方

  • IO函子中的_value是一个函数,这里是把函数作为值来处理
  • IO函子可以把不纯的动作存储到_value中,延迟执行这个不纯的操作(惰性执行),包装当前的纯操作
  • 把不纯的操作交给调用者来处理

实现这个函数我们需要用到函数组合的一些概念 可以看看 【函数组合的概念】 这个文章

关于create这个函数我们等会会把具体代码贴出来

const flowRight = create(true)
// IO函子
class IO {
  static of (value) {
    return new IO(function () {
      return value
    })
  }
  constructor(fn) {
    this._value = fn
  }
  map(fn) {
    return new IO(flowRight(fn, this._value))
  }
}
let r = IO.of(process).map(p => p.execPath)
console.log(r)
console.log(r._value())

image.png

完整代码

function flatten(arr) {  
  return arr.reduce((result, item)=> {
      return result.concat(item);
  }, []);
}
function create(isRight){
  return function (...funs) {
    let funList = flatten(funs)
    if(isRight){
      funList.reverse();
    }
    // 这里我们要进行一下判断中是否都是方法体
    const length = funList.length
    let index = length
    while (index--) {
      if (typeof funList[index] !== 'function') {
         throw new TypeError('Expected a function')
      }
    }
    return function(...args) {
      let index = 0
      let result = length ? funList[index].apply(this, args) : args[0]
      while (++index < length) {
        result = funList[index].call(this, result)
      }
      return result
    }
  }
}
const flowRight = create(true)
// IO函子
class IO {
  static of (value) {
    return new IO(function () {
      return value
    })
  }
  constructor(fn) {
    this._value = fn
  }
  map(fn) {
    return new IO(flowRight(fn, this._value))
  }
}
let r = IO.of(process).map(p => p.execPath)
console.log(r)
console.log(r._value())