ReactiveX

Rx的Observable的本质就是一个Event Monad,即上下文(就是图文教程中包裹的盒子)为Event的一个Monad,这里的Event定义,可以对应语言的struct或者enum,包括了next、error和complete三个上下文即可。这里截取的是Swift语言的实现,map方法实现拆装箱(类似Optional,即Haskell的Maybe)

public enum Event<Element> {

/// Next element is produced.

case next(Element)

/// Sequence terminated with an error.

case error(Swift.Error)

/// Sequence completed successfully.

case completed

}

extension Event {

/// Maps sequence elements using transform. If error happens during the transform .error

/// will be returned as value

public func map<Result>(_ transform: (Element) throws -> Result) -> Event<Result> {

do {

switch self {

case let .next(element):

return .next(try transform(element))

case let .error(error):

return .error(error)

case .completed:

return .completed

}

}

catch let e {

return .error(e)

}

}

}

而Rx的subscribe方法就是一个解包,也就是Monad<Event>.map(),接收一个(Event) -> void的参数。或者使用更一般直观的三个参数onNext: (Element) -> Void、onError: (Error) -> Void、onCompleted: (Void) -> Void方法(在其他语言实践上,RxJS就是三个function参数,而RxJava为了支持Java7可以使用匿名内部类)

理论:

Monad Event <$> subscribe

示例:

let subscription = Observable<Int>.interval(0.3)

.subscribe { event in

print(event) // unwraped event

}

let cancel = searchWikipedia("me")

.subscribe(onNext: { results in

print(results)

}, onError: { error in

print(error)

})

Rx的Operator是Functor,也就是说(Event) -> Event,因此可以通过Monad不断bind你想要的组合子,直到最终符合UI控件需要的数据

理论:

Monad Event >>= map >>= concat >>= filter >>= map <$> subscribe

示例:

let subscription = primeTextField.rx.text           // Observable<String>

.map { WolframAlphaIsPrime(Int($0) ?? 0) }      // Observable<Observable<Prime>>

.concat()                                       // Observable<Prime>

.filter { $0.isPrime }                          // Observable<Prime>

.map { $0.intValue }                            // Observable<Int>

Promise / Future

Promise本质上也是一个Monad,包裹的上下文就是resolve和reject。

你可能反驳说Promise.then(f)中的f,可以是value => value,而并不是一个被Promise包裹的类型啊。但是实际上,由于JavaScript类型的动态性,Promise.then中直接返回value类型是个语法糖罢了,实际上会处理为value => Promise.resolve(value)

Promise.resolve(1)

.then(v => v+1) //便捷写法罢了,返回的是resolved状态的Promise对象

.then(v => Promise.resolve(v+1)) //完整写法

.then(v => Promise.reject('error ' + v)) //想要返回rejected状态,无便捷方法

.catch(e => console.log(e)) // error 3

原理:

Monad Promise >>= then >>= then >>= catch >>= then

示例:

Promise.resolve(1)

.then(v => {

return v + 1; // 1

}.then(v =>  {

throw new Error('error'); //reject

}.catch(e => {

console.log(e); // error

return Promise.resolve(0);

}.then(v => {

console.log('end', v); // end 0

}

https://dreampiggy.com/2016/11/17/FRP简介—ReactiveCocoa、RxSwift、Bacon以及背后的Functional/

Monad新解-FRP对比——ReactiveCocoa、RxSwift、Bacon以及背后的Functional的更多相关文章

  1. ReactiveCocoa / RxSwift 笔记一

    原创:转载请注明出处 ReactiveCocoa / RxSwift Native app有很大一部分的时间是在等待事件发生,然后响应事件,比如 1.等待网络请求完成, 2.等待用户的操作, 3.等待 ...

  2. RxSwift之路 1#Swift语法知识准备

    RxSwift之路 1#Swift语法知识准备 在开始学习 RxSwift 之前,一定要对 Swift 相关语法有所了解,否则就很难理解为什么可以这样.关于 Swift 的学习其实只要看看 Swift ...

  3. Functor、Applicative 和 Monad(重要)

    Functor.Applicative 和 Monad Posted by 雷纯锋Nov 8th, 2015 10:53 am Functor.Applicative 和 Monad 是函数式编程语言 ...

  4. ReactiveCocoa入门教程:第一部分

    http://www.cocoachina.com/ios/20150123/10994.html 本文翻译自RayWenderlich,原文:ReactiveCocoa Tutorial--The ...

  5. 使用ReactiveCocoa实现iOS平台响应式编程

    使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Prog ...

  6. [转]使用ReactiveCocoa实现iOS平台响应式编程

    原文:http://www.itiger.me/?p=38 使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍 ...

  7. Scalaz(28)- ST Monad :FP方式适用变量

    函数式编程模式强调纯代码(pure code),主要实现方式是使用不可变数据结构,目的是函数组合(composability)最终实现函数组件的重复使用.但是,如果我们在一个函数p内部使用了可变量(m ...

  8. FRP represents an intersection of two programming paradigms.

    FRP represents an intersection of two programming paradigms. Functional programming Functional progr ...

  9. iOS Architecture Patterns

    By Bohdan Orlov on 21 Mar 2016 - 0 Comments iOS FYI: Slides from my presentation at NSLondon are ava ...

随机推荐

  1. 问题集录03--jquery解析json

    先明确2个概念例如: JSON字符串: var str1 = '{ "name": "deyuyi", "sex": "man&q ...

  2. Javascript基础系列之(五)条件语句(逻辑操作符)

    javascript和其它语言一样,逻辑运算主要包括 与运算&& ,或运算 II  和非运算 ! 与运算(&&)是指两个条件都为true时,整个表达式为true,或运算 ...

  3. document.getElementsByTagName

    var elems = document.forms[form_name].getElementsByTagName("INPUT"); getElementsByTagName( ...

  4. 前端(五):JavaScript面向对象之内建对象

    一.数据类型 js中数据类型分为两种,原始数据累次能够和引用数据类型. 1.原始数据类型 Undefined.Null.Boolean.Number.String是js中五种原始数据类型(primit ...

  5. c# 获取文件夹大小

    private long GetDirectorySizeMethod1(string directory) { long directorySize = 0; DirectoryInfo di = ...

  6. Js的核心:找到DOM

    掌握 JavaScript 的核心之一:DOM,能够熟悉DOM相关操作,了解JavaScript事件机制 一.使用getElementById().getElementsByTagName().chi ...

  7. 初学者需要IPython 与 Jupyter Notebook 吗?

    ipython 是 jupyter notebook的前身并拥有ipython的全部功能         jupyter拥有 cell, markdown 整合的功能, 能同时运行代码, 而且是多组的 ...

  8. 配合sublime使用flexible.js实现微信开发页面自适应

    什么是flexible.js 是一个终端设备适配的解决方案.也就是说它可以让你在不同的终端设备中实现页面适配. 是一个用来适配移动端的javascript框架.根据宽度的不同设置不同的字体大小,样式间 ...

  9. CSS3,transform3D立体可拖拽正方体实现原理

    ---恢复内容开始--- 今天咱们来说一下,CSS中的3D效果 .如果你把transform真的掌握的和纯熟的话,就可以直接通过CSS做出很多很炫酷的效果,甚至.轮播图和选项卡都可以通过CSS来做,咱 ...

  10. Python基础-接口与归一化设计、抽象类、继承顺序、子类调用父类,多态与多态性

    一.接口与归一化设计 Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能). 由 ...