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. 使用idea开发工具,nginx服务部署Extjs6,SpringBoot项目到服务器

    编译ExtJs文件 1.输入命令 2.开始编译 3.找到编译后的文件 E:\idea_project\BaiSheng_Model\fin-ui\build\production\Admin 4.将文 ...

  2. [PY3]——找出一个序列中出现次数最多的元素/collections.Counter 类的用法

    问题 怎样找出一个序列中出现次数最多的元素呢? 解决方案 collections.Counter 类就是专门为这类问题而设计的, 它甚至有一个有用的 most_common() 方法直接给了你答案 c ...

  3. mariadb sequence

    MariaDB 10.3 正式版推出后,有了像 Oracle.PostgreSQL 里的序列特性. 同时表字段AUTO_INCREMENT原特性还保持,但是sequence特性在某些特定情境还是很有用 ...

  4. NetMQ:.NET轻量级消息队列

    前言 首先我现在是在一家游戏工作做服务端的,这几天我们服务端游戏做了整个底层框架的替换,想必做过游戏的也都知道,在游戏里面会有很多的日志需要记录,量也是比较大的:在没有换框架之前我们存日志和游戏运行都 ...

  5. 2017年11月30日 C#TreeNode递归&邮箱验证&新用户窗体

    TreeNode递归 递归:自己调用自己一层一层的把数据找出来 TreeNode:可以创建多个节点 private void button1_Click(object sender, EventArg ...

  6. 工厂模式(Factory Pattern)

    一.工厂模式(Factory Pattern)的介绍 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使 ...

  7. Error:Annotation processors must be explicitly declared now.

    环境 Android Studio 3.0 Gradle 3.0.0 gradle 4.1 Error Error:Execution failed for task ':app:javaPreCom ...

  8. Oracle OCI操作UDT相关学习(二)

    沿用 Oracle OCI操作UDT相关学习 一文中定义的类型和表. 1.更改数据 在sqldeveloper 中更新数据, update dxl.cust set addr.street='a11' ...

  9. csharp:DropDownComboxTreeView

    using System; using System.Collections.Generic; using System.Text; using System.Drawing; using Syste ...

  10. 洛谷P2196 挖地雷(dp)

    题意 题目链接 Sol 早年NOIP的题锅好多啊.. 这题连有向边还是无向边都没说(害的我wa了一遍) 直接\(f[i]\)表示到第\(i\)个点的贡献 转移的时候枚举从哪个点转移而来 然后我就用一个 ...