函数式编程思维

本文探讨函数式编程的范畴论基础、核心理论及特性,详细阐述了纯函数、柯里化、point free、高阶函数、尾调用等概念,并介绍了函子、of方法、Maybe和Either函子、ap函子以及Monad在IO操作中的应用,旨在帮助开发者深化对函数式编程的理解。
摘要由CSDN通过智能技术生成

目录

一.范畴论 

二.函数式编程基础理论

三.特性

四.高阶函数

1.纯函数

2.函数的柯里化

3.point free

4.声明式与命令式代码

 5.优缺点

6.惰性函数 

7.高阶函数

8.尾调用

五.函子

六.of方法

七.Maybe函子

八.Either 函子

九.ap 函子

十.Monad函子

十一.IO 操作


一.范畴论 

  1. 函数式编程是范畴论的数学分支是一门很复杂的数学,认为世界上所有概念体系都可以抽象出一个个范畴
  2. 彼此之间存在某种关系概念、事物、对象等等,都构成范畴。任何事物只要找出他们之间的关系,就能定义
  3. 箭头表示范畴成员之间的关系,正式的名称叫做“态射”(morphism)。范畴论认为,同一个范畴的所有成员,就是不同状态的“变形”(transformation)。通过“态射”,一个成员可以变形成另一个成员

二.函数式编程基础理论

  1. 函数式编程其实相对于计算机的历史而言是一个非常古老的概念,甚至早于第一台计算机的诞生。函数式编程的基础模型来源于λ(Lambda x=>x*2)演算,而λ演算并非设计于在计算机上执行,它是在20世纪三十年代引入的一套用于研究函数定义、函数应用和递归的形式系统。
  2. 函数式编程不是用函数来编程,也不是传统的面向过程编程。主旨在于将复杂的函数符合成简单的函数(计算理论,或者递归论,或者拉姆达演算)。运算过程尽量写成一系列嵌套的函数调用。
  3. Javascript是披着c外衣的Lisp
    // 用函数编程,非函数式编程
    function test(){
    
    }
    test()
  4. 真正的火热是随着React的高阶函数而逐渐升温

三.特性

  1. 函数是一等公民。所谓“第一等公民”,指的是函数与其他数据类型一样,传入另一个函数,或者作为别的函数的返回值。
  2. 不可改变变量。在函数式编程中,我们通常理解的变量在函数式编程中也被函数代替了:在函数式编程中变量仅仅代表某个表达式。这里所说的"变量"是不能被修改的。所有的变量只能被赋一次初值
  3. 没有“副作用”
  4. 不修改状态
  5. map和reduce是最常用的函数式编程方法

四.高阶函数

1.纯函数

  • 对于相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用,也不依赖外部环境的状态。
  • var xs = [1,2,3,4];
    //Array.slice是纯函数,因为它没有副作用,对于固定的输入,输出总是固定的
    xs.slice(0,2);
    xs.splice(0,2);    //会改变源数据,非纯函数

    优缺点:

  • import _ from 'loadsh';
    var sin = _.memorize(x => Math.sin(x));
    
    //第一次计算的时候会稍微慢一点
    var a = sin(1);
    
    //第二次有了缓存,速度极快
    var b = sin(1);
    
    
    //纯函数不仅可以有效降低系统的复杂度,还有很多很棒的特性,比如可缓存性
  • //不纯的
    var min = 18;
    var checkage = age => age > min;
    
    //纯的,这很函数式
    var checkage = age => age > 18;
    
    
    //在不纯的版本中,checkage不仅取决于age 还有外部依赖的变量min
    
    //纯的checkage把关键数字18硬编码在函数内部,扩展性比较差,柯里化优雅的函数式可以解决问题
    
    //柯里化之前
    function add(x, y) {
        return x + y
    }
    add(1, 2)
    
    //柯里化之后
    function addX(y) {
        return function (x) {
            return x + y
        }
    }
    addX(2)(1)

2.函数的柯里化

  • 传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
  • var checkage = min => (age => age > min);
    var checkage2 = checkage(18);
    checkage2(20);
    function foo(p1, p2) {
        this.val = p1 + p2;
    }
    var bar = foo.bind(null, 'p1');
    var baz = new bar('p2');
    console.log(baz.val);

    事实上柯里化是一种 “预加载” 函数的方法,通过传递较少的参数,得到一个已经记住了这些参数的新函数,某种意义上讲,这是一种对参数的“缓存”,是一种非常高效的编写函数的方法。

3.point free

  • 把一些对象自带的方法转化成纯函数,不要命名转瞬即逝的中间变量
  • //转变前,我们不关心str这个中间变量
    const f = str => str.toUpperCase().split(' ');
    
    
    //转换后
    var toUpperCase = word => word.toUpperCase();
    var split = x => (str => str.split(x));
    
    var f = compose(split(' '), toUpperCase);
    
    f("abcd efgh")
    
    //这种风格能够帮助我们减少不必要的命名,让代码保持简洁和通用
    
    
    //实现一个compose
    
    function compose(...funcs) {
    
      // 没有传入函数运行直接返回参数
      if (funcs.length === 0) {
        return arg => arg
      }
    
    
      // 只传入一个函数,就返回其本身
      if (funcs.length === 1) {
        return funcs[0]
      }
    
    
      // 核心代码其实就是一句reduce, reduce特性就是按顺序执行,并且将结果传
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值