Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

函数式编程之compose函数的实现(一) #31

Open
qingfengmy opened this issue Jun 23, 2018 · 0 comments
Open

函数式编程之compose函数的实现(一) #31

qingfengmy opened this issue Jun 23, 2018 · 0 comments

Comments

@qingfengmy
Copy link
Owner

举个例子

需求: 加密和解密
加密算法:base64编码,每个字符减一
解密算法:每个字符加一,base64解码

// 加密算法
const encode = function(str) {
  return Base64.encode(str);
};
const addOne = function(str) {
  for (let i = 0; i < str.length; i++) {
    str[i] = str.charCodeAt(i) + 1;
  }
  return str;
};
const str = "你好";
const result1 = addOne(encode(str));
console.log(result1); // 5L2gLOWlvQ==
// 解密
const decode = function(str) {
  return Base64.decode(str);
};
const subOne = function(str) {
  for (let i = 0; i < str.length; i++) {
    str[i] = str.charCodeAt(i) - 1;
  }
  return str;
};
const result2 = decode(subOne(result1));
console.log(result2);// 你好

注意:取字符的ASCII码是str.charCodeAt()方法,其他取到的是字符串和数字相加是NaN

compose实现

const compose1 = function(...args) {
  return function(args1) {
    return args.reduce((arg, func) => func(arg), args1);
  };
};
// 函数从左到右执行
const func = compose1(encode, addOne);
const result1 = func("你好");
console.log(result1);// 5L2gLOWlvQ==

const func1 = compose1(subOne, decode);
const result2 = func1(result1);
console.log(result2);// 你好

需求变化,加密时传入的可能是多参数,需要前置一个函数把多参连接为一个参数

const join = function(...args) {
  return args.join("");
};
// 测试
console.log(join('你','好'))// 你好

这里其实就是为了展示 函数式编程 面对多参时的问题,compose函数做相应修改

/**
 * 1. 第一个函数参数不限,后面的函数参数都是一个
 * 2. 函数执行从左侧开始
 * @param args
 */
const compose1 = function(...args) {
  return function(...args1) {// 多参
    return args.reduce((arg, func) => func(arg), args1);
  };
};
const func = compose1(join, encode, addOne);// 加上join
const result1 = func("你", "好");
console.log(result1);

加密时没问题的,但解密出错,因为解密的第一个函数的参数是字符串,而args是数组,数字没有charCodeAt方法。多参时,问题就改变成如下问题:

const test1 = function(name) {
  console.log("test1", name);
};
const test2 = function(...args) {
  console.log("test2", args); //loga
};
const test = function(...args) {
  console.log(args);
  args.length == 1 && test1(args[0]);
  args.length > 1 && test2(args);
};
// 没问题
test("a");
// 有问题
test("a", "b"); // loga处是 [ [ 'a', 'b' ] ]
test2("a","b")// loga处是 [ 'a', 'b' ]

由上面可以看出,多参数在函数式编程中有无法处理的地方,所以函数式编程要避免多参数,只支持单参数函数,如果有多参数,需要转换为单参数,学名叫柯里化

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant