博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
函数式编程(五)
阅读量:5875 次
发布时间:2019-06-19

本文共 2682 字,大约阅读时间需要 8 分钟。

如果你前面都看完了跟到了这里,我只能说你很棒棒,不过我不得不说,这才刚刚开始。前面我们已经知道如何书写函数式的程序了,但是我们还没提到控制流(control flow)、异常处理(error handling)、异步操作(asynchronous actions)和状态(state)呢?

容器

容器为函数式编程里普通的变量、对象、函数提供了一层极其强大的外衣,赋予了它们一些很惊艳的特性

按照我们的惯例,先从最简单的容器入手。

var Container = function(x) {  this.__value = x;}Container.of = function(x) { return new Container(x); };

试着执行以下Container.of(3),看看输出的值。

jQuery $(...) 返回的对象并不是一个原生的 DOM 对象,而是对于原生对象的一种封装,某种意义上就是一个“容器”。
我们接着添加一个map方法

Container.prototype.map = function(f){  return Container.of(f(this.__value))}Container.of(3)    .map(x => x + 1)                //=> Container(4)    .map(x => 'Result is ' + x);    //=> Container('Result is 4')

这个跟前面我们提到的数组操作的map方法非常类似,数组的map方法返回一个新的数组,Container的map方法返回一个新的Container。

上面的这个具有map方法的容器就是我们接下来要引出来的函子。

Functor(函子)是实现了 map 并遵守一些特定规则的容器类型。

Functor 是一个对于函数调用的抽象,我们赋予容器自己去调用函数的能力。当 map 一个函数时,我们让容器自己来运行这个函数,这样容器就可以自由地选择何时何地如何操作这个函数,以致于拥有惰性求值、错误处理、异步调用等等非常牛掰的特性

接着我们看看牛掰的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.of("Malkovich Malkovich").map(match(/a/ig));//=> Maybe(['a', 'a'])Maybe.of(null).map(match(/a/ig));//=> Maybe(null),代码并没有报错,我们在对函数调用时,检查了函数是否为空

我们如果不想一值.map .map, 可以用柯里化函数对上面的代码稍微改进一下

var map = curry((f, any_functor_at_all) => any_functor_at_all.map(f));

错误处理

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 getAge = user => user.age ? Right.of(user.age) : Left.of("ERROR!");getAge({name: 'stark', age: '21'}).map(age => 'Age is ' + age);getAge({name: 'stark'}).map(age => 'Age is ' + age);//Left 会终端机链式调用

最后来看下我们不得不做的IO操作

let readLocalStorage = () => {    return window.localStorage;}

机智的改造成纯函数

let readLocalStorage = () => {    return () => {window.localStorage};}

然而并没有什么软用

var IO = function(f) {  this.__value = f;}IO.of = function(x) {  return new IO(() => x);}IO.prototype.map = function(f) {  return new IO(_.compose(f, this.__value));}
var io_window = new IO(function(){ return window; });io_window.map(function(win){ return win.innerWidth });io_window.map(_.prop('location')).map(_.prop('href')).map(split('/'));var $ = function(selector) {  return new IO(function(){ return document.querySelectorAll(selector); });}$('#myDiv').map(head).map(function(div){ return div.innerHTML; });

转载地址:http://vpkix.baihongyu.com/

你可能感兴趣的文章
C/C++ 多线程机制
查看>>
js - object.assign 以及浅、深拷贝
查看>>
python mysql Connect Pool mysql连接池 (201
查看>>
Boost在vs2010下的配置
查看>>
android camera(四):camera 驱动 GT2005
查看>>
一起谈.NET技术,ASP.NET伪静态的实现及伪静态的意义
查看>>
20款绝佳的HTML5应用程序示例
查看>>
string::c_str()、string::c_data()及string与char *的正确转换
查看>>
11G数据的hive初测试
查看>>
如何使用Core Text计算一段文本绘制在屏幕上之后的高度
查看>>
==和equals区别
查看>>
2010技术应用计划
查看>>
XML 节点类型
查看>>
驯服 Tiger: 并发集合 超越 Map、Collection、List 和 Set
查看>>
Winform开发框架之权限管理系统改进的经验总结(3)-系统登录黑白名单的实现...
查看>>
Template Method Design Pattern in Java
查看>>
MVC输出字符串常用四个方式
查看>>
LeetCode – LRU Cache (Java)
查看>>
JavaScript高级程序设计--对象,数组(栈方法,队列方法,重排序方法,迭代方法)...
查看>>
【转】 学习ios(必看经典)牛人40天精通iOS开发的学习方法【2015.12.2
查看>>