阅读 291

我这废柴怎么可能逆袭的一生、第五天

无所事事的样子开始了摸鱼的一天

函数组合

函数组合要满足结合律,即组合内的函数可以任意函数组合为一组 柯里化函数的参数要

    const _ = require('lodash');
    const split = _.curry((sep,str) => _.split(str,sep));
    const join = _.curry((sep,arr) => _.join(arr,sep));
    const f = _.flowRight(join('-'),_.toLower,split(' '));
    console.log(f('HELLO WORLD'));
    const log = v => {
        console.log(v); // 调试用函数组合
        return v;
    }
    const f = _.flowRight(join('-'),log,_.toLower,log,split(' '));
    console.log(f('HELLO WORLD'));
    
    const map = _curry(fn,arr) => _.map(arr,fn);
    const f = _.flowRight(join('-'),log,map(_.toLower),split(' '));
    console.log(f('HELLO WORLD'));
    
    const trace = _.curry((tag,v)=> {
        console.log(tag , v); // log函数改造
        return v;
    });
    const f = _.flowRight(join('-'),trace('map 之后'),map(_.toLower),trace('split 之后'),split(' '));
复制代码

lodash的fp模块,函数优先,数据置后 lodash模块,数据优先,函数置后 lodash模块的使用的时候需要自己把代码柯里化处理,fp模块则不用

    const fp = require('lodash/fp');
    const f = fp.flowRight(fp.join('-'),fp.map(fp.toLower),fp.split(' '));
    console.log(f('HELLO WORLD'));
复制代码

Point Free

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些基本的运算函数
    普通模式
    function f(word){
        return word.toLowerCase().replace(/\s+/g,'_');
    }
    Point Free模式
    const fp = require('lodash/fp');
    const f = fp.flowRight(fp.replace(/\s+/g,'_'),fp.toLower);
    // 函数组合的过程中不需要指明处理的数据
复制代码
    // world wild web  ===> W. W. W
    const fp = require('lodash/fp');
    const firstLetterToUpper = fp.flowRight(fp.join('. '),fp.map(fp.first),fp.map(fp.toUpper),fp.split(' '))
    // 优化下
    const firstLetterToUpper = fp.flowRight(fp.join('. '),fp.map(fp.flowRight(fp.first,fp.toUpper)),fp.split(' '))
    // 每次map都会遍历一次数组,减少map次数可以优化
    console.log(firstLetterToUpper('world wild web'))
复制代码

函子(我是老子)

  • 容器:包含值和值的变形关系(这个关系就是函数)
  • 函子:是一个特殊的容器,通过普通的对象来实现,该对象具有map方法,map方法可以运行一个函数对值进行处理

一个盒子,对外公布一个map方法,用来接受参数,这个参数就是一个对值进行处理的函数

    class Container{
        constructor (value){
            this._value = value;
        }
        map(fn){
            return Container.of(fn(this._value));
        }
        static of(value){
            return new Container(value);
        }
    }
    let r = new Container(666)
     .map(x => x*x)     // 返回的还是一个函子,可以继续链式调用了呢
     .map(x => x++)
    console.log(r); // 返回的是一个函子,而不是value
    
    let r = Container.of(666)
     .map(x => x*x)     // 返回的还是一个函子,可以继续链式调用了呢
     .map(x => {
         console.log(x); // 永远不对外公布函子内的值,只在map内操作
     })
复制代码
  • 函数式编程的运算不直接操作值,而是有函子完成
  • 函子就是实现了一个map方法的对象
  • 函子可以看做一个黑盒子,黑盒子内封装了值
  • 处理黑盒子里的值,需要给黑盒子的map方法传递一个处理值的函数,由传递过来的函数处理值
  • map方法还是会返回一个包含处理过的值的一个函子

MayBe函子

    class MayBe{
        constructor (value){
            this._value = value;
        }
        map(fn){
            return isNothing() ? MayBe.of(null) : MayBe.of(fn(this._value));
        }
        static of(value){
            return new MayBe(value);
        }
        isNothing(){
            return this._value ===null||this._value === undefined ;
        }
    }
     let r = MayBe.of('hello')
     .map(x => x.toUpperCase())
     .map(x => null)        // 某一时刻传入null了,在最终结果的时候无法得知
     .map(x => x.split(' '))
复制代码

Either函子

类似与if...else...的解决MayBe函子出现的null

    class left {
        static of(value) {
            return new left(value)
        }
    
        constructor(value) {
            this.value = value
        }
    
        map(fn) {
            return this
        }
    }
    
    class right {
        static of(value) {
            return new right(value)
        }
    
        constructor(value) {
            this.value = value
        }
    
        map(fn) {
            return right.of(fn(this.value))
        }
    }
    
    function parseJSON(str) {
        try {
            return right.of(JSON.parse(str))
        } catch (e) {
            return left.of({error: e.message})
        }
    }
    
    let res = parseJSON('{"name":"asd"}')
        .map((res) => {
            return res.name.toUpperCase()
        })
    console.log(res)
复制代码

—————————————————————————————————————————————————————— 我这废柴

系列

文章分类
前端
文章标签