Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

IO functor

preface

We have studied several functors in previous articles

  • MayBe functor
  • Either functor

Let’s move on to a new chapter

The difference between the IO functor and the previous functor

  • IO functorIn the_valuePhi is a function, and we’re treating the function as a value
  • IO functorImpure actions can be stored to_valueIn, the impure operation is deferred (lazy execution), wrapping the current pure operation
  • Leave impure operations to the caller

To implement this function, we need to use some of the concepts of function composition. See the article “The concept of function composition”

We’ll post the code for create in a moment

const flowRight = create(true)
/ / IO functor
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())
Copy the code

The complete code

function flatten(arr) {  
  return arr.reduce((result, item) = > {
      returnresult.concat(item); } []); }function create(isRight){
  return function (. funs) {
    let funList = flatten(funs)
    if(isRight){
      funList.reverse();
    }
    // check if all methods are method bodies
    const length = funList.length
    let index = length
    while (index--) {
      if (typeoffunList[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 functor
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())
Copy the code