函数式编程

2021/4/22 20:28:47

本文主要是介绍函数式编程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

函数式编程
对运算过程进程抽象,描述数据(函数)之间的映射 面向对象编程: 对现实事务和业务逻辑抽象成程序中的类和对象,通过封装,继承和多态来演示事物的联系
优点
  1. 代码细粒化
  2. 代码重用
  3. 可以抛弃this
  4. vue3,react开始拥抱函数式编程,利于开发
纯函数
相同的输入必须有相同的输出,不改变原数据、没有副作用
高阶函数
1.函数做为入参, (使原函数处理多样化) 2. 函数作为返回值
  1. 帮我们屏蔽细节,让我们关注代码逻辑
  2. 用来抽象通用问题 (forEach,filter)
闭包 (closure )
函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能释放,因此函数依然可以访问外部函数的成员。 好处: 延长了变量的可访问范围,外部可以访问函数内部变量,延长我们需要数据的生命周期,提高效率
柯里化
把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的,这个过程就被称为柯里化
_.curry 函数组合
  • 将细粒度的函数进行组合成功能相对复杂的函数;
  • 一般运用纯函数和柯里化函数和管道函数等技术进行组合。
  • 函数组合需要遵从“组合率”: 函数组合顺序调整的话,返回的结果都应该是一样的
  • lodash/fp 模块全部都是纯函数,都是柯里化函数
const flowRight = (...arg) => (v) => arg.reverse().reduce((pre, curr, ) => curr(pre) , v); 组合函数的调试 const track = _.curry((tag, v) => { console.log(tag,v); return v }) pointfree 函数式编程的模式
把数据处理的过程定义为与数据无关的合成运算,不需要用到代表数据的那个参数,只是把简单的运算过程合成在一起,在此之前我们需要定义一些符合这些条件的基本辅助函数
  • 不需要指明需要处理的
  • 抽象运算过程
  • 定义细粒度的辅助函数
  • 把一系列运算函数合成函数组合
Functor (函子) 容器:包含值和值的变形关系(这个变形关系就是函数) 定义
函子:是个特殊的容器,通过一个普通的对象来实现,该对象具有map方法,map可以运行一个函数对数据进行变形处理 函子对象内部会保存一个数据,并且会提供一个map方法,map方法可以传入一个处理函子对象内部数据的函数,并且map方法返回 一个新的函子对象
  1. 函子是一个盒子
  2. 盒子内保存一个值、
  3. 通过调用盒子的map方法可以传入一个函数,这个函数对盒子内部的数据进行处理,
  4. 调用map方法返回一个新的函子,这样就可以进行链式操作
class Container { static of (value) { return new Container(value); } constructor(value) { this._value = value; } map(fn) { return Container.of(fn(this._value)); } } maybe函子
对函子进行参入数据异常进行处理的函子
class Maybe { static of (value) { return new Maybe(value); } constructor(value) { this._value = value; } map(fn) { return this.isEmpty() ? Maybe.of(this._value) : Maybe.of(fn(this._value)); } isEmpty () { return this._value === null || this._value === undefined } } either函子
就是对函数异常进行处理的函子
lass Left { static of (value) { return new Left(value); } constructor(value) { this._value = value; } map(fn) { return this } } function eitherFn (data) { try { return Container(data) } catch (error) { return Left({msg: error}) } } io函子
对函数副作用进行延后操作
/ 将传入的数据包在函数中 // 把通过map传入的处理数据的方法通过flowRight组合起来 // 这样就将副作用进行延后处理,副作用在函数调用时才会产生 // 只有执行函子的_value()时,函数才会被调用,并返回数据 class IO { static of (value) { return new IO(function () { return value }); } constructor(fn) { this._value = fn; } map(fn) { return new IO(fp.flowRight(fn, this._value)); } } monad函子
避免io函子嵌套问题,让过程扁平化
class Monad { static of (value) { return new IO(function () { return value }); } constructor(fn) { this._value = fn; } map(fn) { return new IO(fp.flowRight(fn, this._value)); } join() { this._value() } floatMap(fn) { // 将Monad函子组合到处理过程中,执行上一段函子的处理过程,并返回Monad函子 return this.map(fn).join() } } let readFile = function (filename) { return new Monad(function () { return false.readFile(filename,"utf-8"); }) } let print = function (x) { return new Monad(function () { console.log(x); return x; }) } let r = readFile("aa.json") .floatMap(print) .join() // 调用处理过程并返回 folktale (佛克忒哦)
函数式编程库,里面有task模块,用于解决异步函数式编程 里面有常用的函子可以直接拿来用


这篇关于函数式编程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程