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. Android OpenGL教程-第三课【转】

    第三课 给多边形上色: 作为第二课的扩展,我将叫你如何使用颜色.你将理解两种着色模式,在左图中,三角形用的是光滑着色,四边形用的是平面着色. 这次增加的代码不算多. 增加一个color的buffer ...

  2. Java入门系列-21-多线程

    什么是线程 在操作系统中,一个应用程序的执行实例就是进程,进程有独立的内存空间和系统资源,在任务管理器中可以看到进程. 线程是CPU调度和分派的基本单位,也是进程中执行运算的最小单位,可完成一个独立的 ...

  3. Java入门系列-14-深入类和对象

    这篇文章用大量的代码帮你搞懂:值传递和引用传递.构造方法.方法重载.static关键字的使用 方法参数传递-值传递和引用传递 1.值传递 敲一敲: /** * 使用方法交换两个变量的值 * @auth ...

  4. bitbucket 源代码托管

    5个人以下可以免费使用,不限制仓库的数量; 国外的注册需要开启蓝灯FQ; 1.注册账号 maanshancss w1-g1@qq.com;创建仓库; 然后拷贝现有项目 然后提交 然后push; 2.写 ...

  5. 另一个C#模拟post请求的例子

    private string returninstallTmnl(AddTmnlInstallParameter model) { string url = ConfigurationSettings ...

  6. window.open()被浏览器拦截问题汇总

    一.问题描述 最近在做项目的时候碰到了使用window.open被浏览器拦截的情况,虽然在自己的环境可以对页面进行放行,但是对用户来说,不能要求用户都来通过拦截.何况当出现拦截时,很多用户根本不知道发 ...

  7. 一、mysql架构

    一.简介 mysql是一个开源的数据库管理系统,它相对于oracle更加地轻量.成本低,随着功能的日益完善,它变得备受企业喜爱,尤其是中小企业. mysql的整体架构大体包括以下几个方面: 1)主体结 ...

  8. java.lang.RuntimeException: Canvas: trying to draw too large(107331840bytes) bitmap.

    环境: Android 8.0.1 MIUI 真机测试闪退 gradle 4.1 compileSdkVersion 26 buildToolsVersion '26.0.2' minSdkVersi ...

  9. Sqoop迁移Hadoop与RDBMS间的数据

    Sqoop是用来实现结构型数据(如:关系型数据库RDBMS)和Hadoop之间进行数据迁移的工具.它充分利用了MapReduce的并行特点以批处理的方式加快数据的传输,同时也借助MapReduce实现 ...

  10. PAT 1082. Read Number in Chinese

    #include <cstdio> #include <cstdlib> #include <string> #include <vector> #in ...