为了方便自己学习以及理解,把自己的学习笔记放在网上,可以在上班或在家忘记的时候拿出来看看(仅供自己参考)
当一个函数有多个参数的时候先传递一部分参数调用它(这部分参数以后永远不变)
返回一个新的函数接收剩余的参数,返回结果
总结:
1.可以让我们给一个函数传递较少的参数得到一个已经记住了某些固定参数的新函数
2.这是一种对函数参数的"缓存"
3.让函数变得更灵活,让函数的粒度更小
4.可以把多元函数换成一元函数,可以组合使用函数产生强大的功能
function curry(fn, args) { const len = fn.length; args = args || []; return function() { const subArgs = args.slice(); for (let i = 0; i < arguments.length; i++) { subArgs.push(arguments[i]); }; if (subArgs.length >= len) { return fn.apply(this, subArgs); } else { return curry.call(this, fn, subArgs); }; }; };
function compose(...args) { args = args.reverse(); return function(value) { return args.reduce((res, fn) => fn(res), value); }; };
定义:可以把数据处理的过程定义成与数据无关的合成运算,不需要用到代表数据的那个参数,只要把简单的运算步骤合成到一起,在这种模式之前我们需要定义一些辅助的基本运算函数
//Hello World => hello_world const f = fp.flowRight(fp.replace(/\s+/g, "_"), fp.toLower); console.log(f("Hello World")); // world wild web ==>W. W. W //const firstLetterToUpper = fp.flowRight(fp.join(". "),fp.map(fp.first), fp.map(fp.toUpper), fp.split(" ")); const firstLetterToUpper = fp.flowRight(fp.join(". "), fp.map(fp.flowRight(fp.first, fp.toUpper)), fp.split(" "));
class Container { constructor(value) { this._value = value; }; map(fn) { return Container.of(fn(this._value)); }; static of (value) { return new Container(value); }; }; const r = Container.of(5) .map(x => x + 2) .map(x => x * x);
class MayBe { static of (value) { return new MayBe(value); }; constructor(value) { this._value = value; }; map(fn) { return this.isNothing() ? MayBe.of(null) : MayBe.of(fn(this._value)); }; isNothing() { return this._value === null || this._value === undefined; }; };
class Left { static of (value) { return new Left(value); }; constructor(value) { this._value = value; }; map(fn) { return this; }; }; class Right { static of (value) { return new Right(value); }; constructor(value) { this._value = value; }; map(fn) { return Right.of(fn(this._value)); }; }; function parseJson(str) { try { return Right.of(str); } catch (e) { return Left.of({ error: e.message }); }; }; // const r = parseJson('{ name: zs }'); // console.log(r); const r = parseJson('{ "name": "zs" }') .map(x => x.name.toUpperCase()); console.log(r);
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)); }; };
//folktale const { compose: ftCompose, curry: ftCurry } = require("folktale/core/lambda"); const f = ftCurry(2, (x, y) => { return x + y; }); // console.log(f(1,2)); // console.log(f(1)(2)); const f = ftCompose(fp.toUpper, fp.first); //Task处理异步 const fs = require("fs"); const { task } = require("folktale/concurrency/task"); function readFile(filename) { return task(resolver => { fs.readFile(filename, "utf-8", (err, data) => { if (err) { resolver.reject(err); }; resolver.resolve(data); }); }); }; readFile("package.json") .map(fp.split("\n")) .map(fp.find(x => x.includes("version"))) .run() .listen({ onRejected: err => { console.log(err); }, onResolved: value => { console.log(value); } });
//IO函子的问题 // 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)); // }; // }; 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)); }; join() { return this._value(); }; flatMap(fn) { return this.map(fn).join(); } }; const reaFile = function(filename) { return new IO(function() { return fs.readFileSync(filename, "utf-8"); }); }; const print = function(x) { return new IO(function() { console.log(x); return x; }); }; const cat = fp.flowRight(print, readFile); //IO(IO(x)) // const r = cat("package.json")._value()._value(); const r = reaFile("package.json") .flatMap(print) .join(); console.log(r);
JavaScript不像其他语言,即使JavaScript有面向对象的使用方式,但那只不过是语法糖,归根结底还是使用了原型,只不过是用原型的方式来模拟了面向对象而已,现在不管是React还是Vue已经都开始使用函数式编程的思想,而我个人也觉得函数式编程才应该是JavaScript编写代码的核心所在,不过,也需要注意编写代码的时候,其实也不一定要刻意使用函数式编程,最重要的还是怎么方便怎么来。