函数式编程(纯函数、柯里化、函数组合、函子、接口幂等性)
创始人
2024-03-19 21:06:06
0

目录​​​​​​​

纯函数

可缓存

loadsh中memoize缓存函数简单实现

副作用

示例 

接口的幂等性

函数的柯里化

lodsh中的curry方法简单实现

lodash中的fp模块

函数的组合

lodash中的flowRight方法简单实现

函子Functor 

IO函子

其它函子详细介绍


纯函数

对于相同的输入函数,始终得到相同的输出。

可缓存

因为存函数对相同的输入始终有相同的输出,所以可以把纯函数的的结果缓存起来。

loadsh中memoize缓存函数简单实现

function memoize(f){let cache = {}return function () {let arg_str = JSON.stringify(arguments);cache[arg_str] = cache[arg_str] || f.apply(f, arguments);return cache[arg_str];}
}
function getSum(a, b){console.log('执行了')return a + b;
}
const cacheSum = memoize(getSum);
cacheSum(1,2);
cacheSum(1,2);

副作用

如果函数依赖外部的状态就无法保证输出相同,就会带来副作用(让一个函数变为不纯)。

示例 

例如下面当mini改变时就会给checkAge带来副作用(相同的输入,输出不同)。 

let mini = 18;
function checkAge(age) {return age >= mini
}

副作用一般来源于:

  • 配置文件
  • 数据库
  • 获取用户的输入
  • ... 

接口的幂等性

接口可重复调用,在调用方多次调用的情况下,接口最终得到的结果是一致的。

函数的柯里化

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

function checkAge(min, age) {return age >= min;
}
// 柯里化后
function checkAge(min) {return function(age) {return age >= min;}
}

lodsh中的curry方法简单实现

function curry(func) {return function curriedFn(...args) {if(args.length < func.length) {return function() {// 注意arguments参数是类数组需要通过Array.from转化为数组return curriedFn(...args.concat(Array.from(arguments)))}}return func(...args)}
}
function getSum(a, b, c){return a + b + c;
}
const curried = curry(getSum);
curried(1, 2, 3);
const sumBC = curried(1)
sumBC(2, 3);

lodash中的fp模块

其中map、split等函数都用了函数柯里化。当只传入一个参数时,返回的是一个函数。

const fP = require('lodash/fp');
fp.map(fp.toUpper,['a', 'b', 'c']);
const toUpper = fp.map(fp.toUpper);
toUpper(['a', 'b', 'c']);
fp.split(' ', 'hello world');
const split = fp.split(' ');
split('hello world');

函数的组合

如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程的函数和并成一个函数(g(f(x)) => h(g,f))。

lodash中的flowRight方法简单实现

function flowRight(...args) {return function(value) {return args.reverse().reduce(function(acc, fn) {return fn(acc)}, value)}
}
const reverse = arr => arr.reverse()
const first = arr => arr[0]
const f = flowRight(first, reverse)
f([1, 2, 3])

数组reduce方法介绍

JavaScript中常用函数方法(数组篇)_YF-SOD的博客-CSDN博客_javascript数组函数

 

函子Functor 

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

容器:包含值和值的变形关系,这个变形关系就是函数。

class Container {static of (value) {return new Container(value)}constructor (value) {this._value = value}map (fn) {return this._value ? Container.of(fun(this._value)) : Container.of(null)}
}
let r = Container.of(4).map(x => x * x) 

IO函子

IO函子中的_value是一个函数,这里把函数作为值来处理。

IO函子可以把不纯的动作存储在_value中,延迟执行这个不纯的操作,把不操作交给调用者处理。

const fp = require('lodash/fp')
class IO {static of (x) {return new IO(function () {return x;})}constructor (fn) {this._value = fn}map(fn) {return new IO(fp.flowRight(fn, this._value))}
}
let r = IO.of(process).map(p => p.execPath)
r._value()// 返回该文件路径

其它函子详细介绍

函子(Functor、Pointed、Maybe、Either、Mona式d、IO、Ap) - 知乎

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...