函数式编程

本文首发于我的GitHub博客,其它博客同步更新。


函数式编程

什么是函数式编程

  • 程序的本质:根据输入通过某种运算获得相应的输出
  • “函数”:数学中的函数即映射关系:y = sin(x),y和x的关系
  • 纯函数:相同的输入始终要得到相同的输出
  • 作用:函数式编程就是用来描述数据之间的映射

函数的特性

函数是一等公民

  • 1.函数可以存储在变量中
  • 2.函数作为参数(高阶函数)
  • 3.函数作为返回值(高阶函数)

高阶函数

  • 可以把函数作为参数传递给另一个函数

    • 优点:灵活、不需要考虑函数内部如何实现
  • 可以把函数作为另一个函数的返回值

闭包

  • 定义:函数和周围的状态(词法环境)的引用捆绑在一起形成闭包
  • 可以在另一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员

函数式的基础

纯函数

  • 定义:相同的输入永远会得到相同的输出,且没有副作用
  • 类似映射关系y = f(x)
  • 功能库:lodash

    • 纯函数必须有输入和输出
    • 函数式编程不会保留计算中间的结果,所以变量不可变(无状态的)
    • 可以把一个函数的执行结果交给另一个函数处理

副作用

  • 外部因素对程序结果的影响
  • 来源:配置文件、数据库、获取用户的输入……

柯里化

  • 定义:调用一个函数只传递部分的参数,并且返回新的函数,新函数去接受剩余的参数,并且返回相应的结果

    • 当一个函数有多个参数的时候,先传递一部分参数调用它(这部分参数以后永远不变)
    • 然后返回一个新的函数接收剩余的参数,返回结果
  • Lodash里的柯里化

    • _.curry(func)
    • 功能:该函数接收一个或者多个func的参数,如果func所需要的参数都被提供则执行func并返回执行的结果,否则继续返回该函数并等待接收剩余的参数
    • 参数:需要柯里化的函数
    • 返回值:柯里化后的函数

管道

函数组合

  • 定义:如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数合并成一个函数
  • 通俗:函数就像是数据的管道,函数组合就是把这些管道连接起来,让数据穿过多个管道形成最终结果
  • 函数组合默认是从右到左执行
  • loadsh中的组合函数

    • _.flow()从左到右运行
    • _.flowRight()从右到左运行
  • 满足结合律:即,可以把g和f结合,还可以把f和g结合

函子

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

  • 通过函控制副作用,也可以进行异常处理、异步操作等
  • 函数式编程的运算不直接操作值,而是由函子完成
  • 函子就是一个实现了map契约的对象
  • 函子就是一个盒子,盒子封装了一个值
  • 处理盒子的值,需要给map方法传递一个处理值得函数(纯函数)
  • 最终map方法会返回一个包含新值的盒子(函子)

Functor

MayBe

  • 函子处理空值问题

    • map内部进行三元判断

Either

  • Either函子可以用来做异常处理

    • 使用try{...}catch{...}分别调用两个函子对象,一个返回传入函数,一个返回正常输出结果

IO

  • _value作为一个函数处理,把不纯的操作交给调用者来处理

Task

  • folktale标准函数式编程库

    • 处理异步任务

Monad

  • 解决函子嵌套问题IO(IO(x))

    • 利用join、flatMap返回_value
面向对象:把事物抽象成程序中的类和对象,通过封装、继承和多态演示事物联系(抽象事物)
阅读 78

推荐阅读