• [Functional Programming] 1. Function modelling -- Combine functions


    Let's say we have two fucntions:

    const toUpper = s => s.toUpperCase();
    const exclaim = s => `${s}!`;

    We want to combine those. 

    But function itself doesn't give us method to combine tow functions.

    Therefore we can create a Monoid to combine function:

    const Fn = run => ({
       run,
       concat(otherFn) {
        
       }
    })
    

    So 'Fn' take a 'run' function as arguement and because we want to combine different function, we need to implement the interface for monoid 'concat'.

    Inside 'concat' function, first, it should return 'Fn', so that we can compose later.

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn()
       }
    })
    

    Becasue 'Fn' take a function, what we want is running the Fn with passed in data first then running other Fn with the same data.

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn(x => run(x).concat(otherFn.run(x)))
       }
    })
    

    The highlighted 'concat' function is 'String.prototyp.concat', not the 'Fn.concat'. Because 'String' is semigroup, so we can do 'concat'.

    Now, if we runt the code:

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn(x => run(x).concat(otherFn.run(x)))
       }
    })
    
    const toUpper = s => s.toUpperCase();
    const exclaim = s => `${s}!`;
    
    const res = Fn(toUpper)
      .concat(Fn(exclaim))
      .run("happy flow"); // HAPPY FLOWhappy flow!
    

      


    Functor

    We can also make 'Fn' as a Functor. All we need to do is add 'map' function to it.

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn(x => run(x).concat(otherFn.run(x)))
       },
       map(f) { 
       }
    })
    

      

    Inside 'map'. We always need to return a 'Fn' in order to keep chaining the call:

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn(x => run(x).concat(otherFn.run(x)))
       },
       map(f) { 
          return Fn()
       }
    })
    

      

    And 'Fn' take a 'function' as arguement to do trasformation.

    map(f) { 
          return Fn(f => f(...))
       }

    Inside 'f(...)', we need to get the value by calling 'run(x)':

    const Fn = run => ({
       run,
       concat(otherFn) {
          return Fn(x => run(x).concat(otherFn.run(x)))
       },
       map(f) { 
          return Fn(f => f(run(x)))
       }
    })
    

      

    Example:

    const res = Fn(toUpper)
      .concat(Fn(exclaim))
      .map(s => s.slice(5))
      .run("happy flow"); //  FLOWhappy flow!
  • 相关阅读:
    初始化生成linux sysfs(8)
    内存延迟监控系统组件
    数组代码First Missing Positive
    类文件Spring中空值的写法java教程
    状态键盘完美适应iOS中的键盘高度变化
    框架绑定JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember
    域编码jquery的AJAX跨域请求及跨域请求的原理
    数据格式利用GSON接卸JSON数据
    网元查看一个无厘头的core dump问题定位
    类型应用oracle如何显示毫秒?
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12483956.html
Copyright © 2020-2023  润新知