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. java文件在没有安装jdk的windows下运行。

    1.首先该工程最好是gui的,使用swing或者awt的都行. 2.使用eclipse打包jar文件. 项目名字上面点右键,选择Export,在选择java\JAR file.    选择src文件夹 ...

  2. 深入redis内部---网络编程

    Redis在anet.h和anet.c中封装了底层套接字实现: 1.anetTcpServer,建立网络套接字服务器,完成对socket(),bind(),listen()等操作的封装,返回socke ...

  3. flask之flask-login登陆验证(一)

    这个模块能帮助我们做很多事,最常用到的是,登陆验证(验证当前用户是否已经登陆).记住我功能 一 安装 pip install flask-login 二 导入相关模块及对象并初始化 from flas ...

  4. Docker安装和状态查询指令

    1 .安装 Docker $ yum install -y docker-engine 2.启动docker $systemctl start docker.service 3.验证安装是否成功(有c ...

  5. svg基础知识体系建立

    一.简介:SVG 是使用 XML 来描述二维图形和绘图程序的语言. SVG 指可伸缩矢量图形 (Scalable Vector Graphics) SVG 用来定义用于网络的基于矢量的图形 SVG 使 ...

  6. tp3.2开启允许跨域

    在入口文件<?PHP下加上 header('Access-Control-Allow-Origin:*');header("Access-Control-Allow-Headers: ...

  7. Java—IO流 对象的序列化和反序列化

    序列化的基本操作 1.对象序列化,就是将Object转换成byte序列,反之叫对象的反序列化. 2.序列化流(ObjectOutputStream),writeObject 方法用于将对象写入输出流中 ...

  8. 使用C++11新特性来实现RAII进行资源管理

    方法一:借助auto.decltype.unique_ptr.Lambda表达式构造 sqlite3 *db = NULL; auto deleter = [](sqlite3 *pdb){sqlit ...

  9. 深入理解java的形参和实参

    转载声明:本文转载自公众号「码匠笔记」. 前几天在头条上看到一道经典面试题,引发了一些思考.也是写这篇文章的导火索. 背景 请看题: public    classMain{    publicsta ...

  10. phantomjs rendering

    http://wwwy3y3.ghost.io/pageres-phantomjs-capture-sreenshot-chinese-fonts-not-render-correctly/ 在使用中 ...