// 参考
// http://jiyinyiyong.github.io/monads-in-pictures/
// https://llh911001.gitbooks.io/mostly-adequate-guide-chinese/content/ch8.html
// https://zhuanlan.zhihu.com/p/21926955
// https://zhuanlan.zhihu.com/p/22094473 // functor就是一个容器
var Container = function(x) {
this.__value = x;
} Container.of = function(x) { return new Container(x); };
Container.of(3); // map函数的参数是一个函数。这个函数用来运算容器里面的值。
Container.prototype.map = function(f){
return Container.of(f(this.__value))
};
Container.of(2).map(function(two){ return two + 2 }).map(function(num){return num * 2 }); // 高级一点的functor,可以处理null的functor。
var Maybe = function(x) {
this.__value = x;
}; Maybe.of = function(x) {
return new Maybe(x);
}; Maybe.prototype.isNothing = function() {
return (this.__value === null || this.__value === undefined);
}; Maybe.prototype.map = function(f) {
return this.isNothing() ? Maybe.of(null) : Maybe.of(f(this.__value));
}; Maybe.prototype.join = function() {
return this.isNothing() ? Maybe.of(null) : this.__value;
} Maybe.of({name: "Boris"}).map(function(obj){return obj['age'] }).map(function(num){return num + 10});
Maybe.of(3).map(function(num){return num + 2; }).map(function(num){return num + 5}); console.log('点的连续运算', Maybe.of(3).map(function(num){return num + 2; }).map(function(num){return num + 5}) );
console.log('函数组合',Maybe.of(function(num){return num + 2}).map(function(num){return num + 3})); // 尽管Maybe会返回null,但是我们不知道它从哪返回,也没有更多异常信息。
// 错误捕获
var Left = function(x) {
this.__value = x;
}
var Right = function(x) {
this.__value = x;
} Left.of = function(x) {
return new Left(x);
};
Right.of = function(x) {
return new Right(x);
}; Left.prototype.map = function(f) {
return this;
};
Right.prototype.map = function(f) {
return Right.of(f(this.__value));
}; var either = function(f, g, e) {
switch(e.constructor) {
case Left: return f(e.__value);
case Right: return g(e.__value);
}
}; var a = Maybe.of({name: "Boris"}).map(function(obj){
if(obj['name']){return Right.of('has age')}
else{
return Left.of('no age');
}
})
// .map(function(num){return num + 10}).map(function(num){return num + 1});
console.log('a',a); // 另类functor,惰性求值,用来接触外面的世界。把副作用操作( IO操作、异步请求、DOM操作)包裹起来。
var IO = function(f) {
this.__value = f;
}; IO.of = function(x) {
return new IO(function() {
return x;
});
}; IO.prototype.map = function(f) {
return new IO(f(this.__value));
}; // 可以链式调用。
// 可以进行函数组合。
// 处理副作用。常见的副作用包括异常和异步。
// 我们很快想到数组也是一个容器functor,该容器的map函数也是用来运算容器里面的值。
// promise也是一个容器functor。 // Applicative是一个起子,用来打开容器。
// 把容器里的函数应用到容器里的值。

函数式functor的理解的更多相关文章

  1. Js中函数式编程的理解

    函数式编程的理解 函数式编程是一种编程范式,可以理解为是利用函数把运算过程封装起来,通过组合各种函数来计算结果.函数式编程与命令式编程最大的不同其实在于,函数式编程关心数据的映射,命令式编程关心解决问 ...

  2. 面试官问:说说你对Java函数式编程的理解

    常见的面试问题 总结一下,在Java程序员的面试中,经常会被问到类似这样的问题: Java中的函数式接口是什么意思? 注解 @FunctionalInterface 的作用是什么? 实现一个函数式接口 ...

  3. 函数式编程——C#理解

    转自:http://www.cnblogs.com/xiaozhi_5638/p/4762846.html 目录 一个问题 函数式编程中的函数 数学与函数式编程 混合式编程风格 一个问题 假设现在我们 ...

  4. java8 Lambda 表达式和函数式接口快速理解

    前言 接上篇文章 java8 新特性 由于上篇过于庞大,使得重点不够清晰,本篇单独拿出 java8 的 Lambda 表达式和函数式接口说明. Lambda 表达式 lambda 表达式其实就是使用了 ...

  5. 如何编写高质量的 JS 函数(3) --函数式编程[理论篇]

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/EWSqZuujHIRyx8Eb2SSidQ作者:杨昆 [编写高质量函数系列]中, <如何 ...

  6. 翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  7. Java8-函数式接口理解及测试

    1.  函数式接口的理解 根据重构的思想,需要把容易变化的模块进行抽象并封装起来,从这个点来看,Java8新引入的函数式接口就是基于这个思想进行设计的. 2. 函数式接口定义 2.1 自定义如下 需要 ...

  8. Scala函数与函数式编程

    函数是scala的重要组成部分, 本文将探讨scala中函数的应用. scala作为支持函数式编程的语言, scala可以将函数作为对象即所谓"函数是一等公民". 函数定义 sca ...

  9. Python学习(26):Python函数式编程

    转自  http://www.cnblogs.com/BeginMan/p/3509985.html 前言 <core python programming 2>说: Python不大可能 ...

随机推荐

  1. XMLtank测试记录

    1.首先就是这个分辨率对于高分屏的电脑适应太差了....立马让我有弃的想法..(如图) 2.游戏结束之后每次都要从第一关开始,很不方便.建议加入选关功能. 3.鼠标控制不方便,尤其是左键和右键分别控制 ...

  2. python中应用*args 与**kwargs

    这是Python函数可变参数 args及kwargs------->目的是:当函数的参数不确定时,可以使用*args 和**kwargs,*args 没有key值,**kwargs有key值. ...

  3. linux scp 远程复制文件

    1.从本机复制文件到远程scp 文件名 远程计算机用户名@远程计算机的ip:远程计算机存放该文件的路径2.从远程复制文件到本机:scp 远程计算机用户名@远程计算机ip:文件名 存放该文件的本机路径3 ...

  4. Redis与Memcache的区别

    Redis与Memcache的区别 数据类型:  redis数据类型丰富,支持set liset等类型          memcache支持简单数据类型,需要客户端自己处理复杂对象 持久性: red ...

  5. MySQL免安装的配置

    ①:下载并获取解压路径: ②:修改 my-default.ini: ③:管理员身份进入cmd,并cd到上面的路径(否则发生错误2,找不到文件): ④:忘记ROOT密码如何重置:

  6. 使用MacBook Air的4项基本技巧

    MacBook Air可以说是笔记本电脑中的翘楚:性能优异.拥有超长的电池使用时间的同时保持了轻盈的体态.纤薄的外形,这几乎满足了人们对笔记本的所有要求.如果你也是一个MacBook Air用户,不妨 ...

  7. python与ruby的差别

    1.引用文件差别 Ruby:同一目录下的文件,如/usr/local/ruby/foo.rb与/usr/local/ruby/bar.rb两个文件.如果直接在foo.rb中 require 'bar' ...

  8. EntityFramework 使用经验

    1.Nuget控制台常用命令 1.获取EntityFramework命令帮助:get-help EntityFramework  2.在项目中启动数据迁移:Enable-Migrations 3.添加 ...

  9. XAF 如何基于业务规则禁用属性

    // Developer Express Code Central Example: // How to: Disable Property Editors Based on a Business R ...

  10. wex5 实战 图片触摸放大移动插件easyzoom的使用与集成

    一 前言 客户的需求就是上帝的召唤. 作为一个开发人员,或者软件从业者,客户的要求就是准则. 遇到一个客户,让我做一个图片放大,但是移动拖拽要定位精准.之前研究过一个hammer插件,多次尝试放大后的 ...