函数式编程初探零

0.前言

函数式编程拥有更好的,组合性,灵活性,容错性,相比面向对象编程。
函数式编程入门,需理解“纯函数”,“柯里化”,“函数组合”这三个概念。
PS:本篇文章的案例使用ramdajs工具库。

1.纯函数

什么是纯函数?
相同输入,相同输出,无副作用。
什么是副作用?请看例子。
demo 1-0:

var array1 = [1,2,3,4,5];
var array2 = [1,2,3,5,5];

// 纯函数,它没有改变array1数组
array1.slice(0,3);
//=> [1,2,3]
array1
//=> [1,2,3,5,5]

// 非纯函数,副作用是改变了array2数组
array2.splice(0,3);
//=> [1,2,3]
array2
//=> [4,5]

demo 1-1:

// 纯函数
var checkAge = function(number) {
  var innerVariable = 12;
  return number >= innerVariable;
};

// 非纯函数,依赖外部变量。因为外部变量不可控,所以副作用是函数返回的值不可控。
var externalVariable = 12;
var checkNumber = function(number) {
  return number >= externalVariable;
};
checkNumber(18);
//=> true
externalVariable = 20;
checkNumber(18);
//=> false

2.柯里化

没有你之前,无可厚非;有了你之后,不可或缺。
你就是柯里化。
那么什么是柯里化?
传给一个函数部分参数,返回一个函数去处理剩余参数。
当然,被柯里化的函数,都是纯函数。
具体理解,请看例子。
demo 2-0

var R = require('ramda');
var minus = function(a, b){ return a- b };
var curryMinus = R.curry( minus );
// R.__是参数占位符
var minus5 = curryMinus( R.__, 5 );
minus5(33);
//=> 28
var minus5Second =curryMinus(5, R.__);
minus5Second(33);
//=> -28

柯里化是函数组合的基础。因为它能保留任何参数的位置。

3.函数组合

相比面向对象的复用,需涉及到类继承的重构,虚方法,重写方法,甚至是抽象类,接口实现等概念,
函数式编程的函数组合概念,则更加自然易懂。
请看例子。
demo 3-0

var R = require('ramda');
var add = R.curry(function (a, b) {
  return a + b;
});
var subtract = R.curry(function(a, b){
  return a - b;
});

// 如果你没有传入参数占位符,缺省选中第一个参数
var add9 = add(9);
var subtract1 = subtract(1, R.__);

// 33这个值先经过subtract1运算,再经过add9运算,从右往左。
var result = R.compose(add9, subtract1);
result(33);
//=> 41

告一段落

在这里,我们已经知道函数式语言的三个基本概念纯函数,柯里化,函数组合。
并且可以运用函数组合,建一个纯函数组成的河流,让数据流动。
但编程里面还有控制流(control flow)、异常处理(error handling)这些概念,
以后有空写续集。
我认为,函数式语言的美妙之处是可以更加清晰地描述事物,相比自然语言。

posted @ 2016-09-22 10:10  草珊瑚  阅读(213)  评论(0编辑  收藏  举报