Open zzz6519003 opened 7 years ago
在 Haskell中,函子类型被定义为:
fmap :: (a -> b) -> f a -> f b 给出一个函数,该函数有一个参数 a,并返回一个 b 和一个有零到多个 a 在其中的函子:fmap 返回一个其中有零到多个 b 的盒子。f a 和 f b 位可以被读为 a 的函子和 b 的函子,意思是 f a 的盒子中有 a,f b 的盒子中有 b。
使用函子很简单 - 只要调用 map() 即可:
const f = [1, 2, 3]; f.map(double); // [2, 4, 6]
恒等 如果将恒等函数(x => x)传递给 f.map(),这里 f 是任何函子,那么结果应该等价于 f(即与 f 有相同含义):
const f = [1, 2, 3]; f.map(x => x); // [1, 2, 3]
下面我们用 JavaScript 再看看组合:
给出一个函子 F:
const F = [1, 2, 3]; 如下的语句都是等同的:
F.map(x => f(g(x)));
// 等同于...
F.map(g).map(f);
很多函数式编程术语都来自于范畴学,范畴学的精髓就是组合。范畴学是最开始很可怕,但是很简单,就像从跳水板跳下或者坐过山车一样。
// trace() 是一个让我们更容易检测内容的实用程序
const trace = x => {
console.log(x);
return x;
};
const u = Identity(2);
// 恒等定律
u.map(trace); // 2
u.map(x => x).map(trace); // 2
const f = n => n + 1;
const g = n => n * 2;
// 组合定律
const r1 = u.map(x => f(g(x)));
const r2 = u.map(g).map(f);
r1.map(trace); // 5
r2.map(trace); // 5
函子之所以牛叉,是有很多原因的。最重要的是,它们是一种抽象,我们可以用它们以作用于任何数据类型的方式来实现很多有用的事情。
http://mp.weixin.qq.com/s/vw_FCdnBpWbxBxXONu0zAg