什么是函数式编程,函数合并与柯里化又是什么意思?

函数式编程在耳边回响了多年,今天就来详细了解一下它吧。

函数式编程的主要特征是:函数是一等公民。它建议大家写纯函数、没有副作用的函数。

讨论完纯函数的内容,我们会看一下最重要的应用:函数的柯里化。

纯函数的概念

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。其中的副作用指的是:跟函数外部环境发生的交互。包括但不限于:

  • 更改文件系统
  • 往数据库插入记录
  • 发送一个 http 请求
  • 可变数据
  • 打印/log
  • 获取用户输入
  • DOM 查询
  • 访问系统状态

例如:slice是纯函数而splice不是。

纯函数的作用

可缓存性

var memoize = function(f) {
  var cache = {};

  return function() {
    var arg_str = JSON.stringify(arguments);
    cache[arg_str] = cache[arg_str] || f.apply(f, arguments);
    return cache[arg_str];
  };
};

var squareNumber  = memoize(function(x){ return x*x; });
squareNumber(4);
//=> 16
squareNumber(4); // 从缓存中读取输入值为 4 的结果
//=> 16

值得注意的一点是,可以通过延迟执行的方式把不纯的函数转换为纯函数:

var pureHttpCall = memoize(function(url, params){
  return function() { return $.getJSON(url, params); }
});

可移植性/自文档化

纯函数对于依赖很诚实,这样就能知道它的目的。可以说是把所有需要的(可变的)参数都传递进来。

可测试性

简单地给函数一个输入,就能有输出了。

合理性

如果一段代码可以替换成它执行所得的结果,而且是在不改变整个程序行为的前提下替换的,那么我们就说这段代码是引用透明的。这样会对理解代码非常重要,因为“可以使用等式推导”(equational reasoning)的技术来分析代码,就是“一对一”替换的情况下手动执行代码。

并行代码

最后一点,也是决定性的一点:我们可以并行运行任意纯函数。因为纯函数根本不需要访问共享的内存,而且根据其定义,纯函数也不会因副作用而进入竞争态(race condition)。

并行代码在服务端 js 环境以及使用了 web worker 的浏览器那里是非常容易实现的,因为它们使用了线程(thread)。不过出于对非纯函数复杂度的考虑,当前主流观点还是避免使用这种并行。

合并

合并就是一个值经过多个函数变化最后输出结果。很明显是一个 reduce 的概念。

比如 a(b(c(d))) 看起来很不舒服,很像 JS 里的回调地域有特别多的大括号。所以我们要是有一个 compose 函数,可以将表达式写成 [c, b, a].compose(d) 该多好,而且如果数组里的函数都是纯函数,甚至还能满足结合律。

function compose(array) {
  return function(args) {
    return array.reduce(function (total, f) {
      return f(total);
    }, args);
  }
}

或者

function compose(array) {
  return function(args) {
    let result = args;
    array.forEach(function(f) {
      result = f(result);
    });
    return result;
  }
}

柯里化

curry 的概念很简单:只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。

function curry(fn) {
  return function finalCurry(...args) {
    if (args.length >= fn.length) {
      return fn(...args);
    } else {
      return function (...args2) {
        return finalCurry(...args, ...args2);
      }
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值