zoukankan      html  css  js  c++  java
  • [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!
  • 相关阅读:
    Ajax缓存解决办法【转】
    【转】关于找工作的鸡零狗碎(续)
    科技爱好者周刊(第 167 期):广告拦截器太过分了
    科技爱好者周刊(第 166 期):视频学习胜过读书吗?
    GitHub镜像
    支付宝小程序环境判断
    怎么样给背景图加透明度
    JavaScript如何实现上拉加载,下拉刷新?
    什么是HTTP? HTTP 和 HTTPS 的区别?
    网页中的一键加QQ群、唤起QQ群聊天窗口
  • 原文地址:https://www.cnblogs.com/Answer1215/p/12483956.html
Copyright © 2011-2022 走看看