Monad新解-FRP对比——ReactiveCocoa、RxSwift、Bacon以及背后的Functional
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的更多相关文章
- ReactiveCocoa / RxSwift 笔记一
原创:转载请注明出处 ReactiveCocoa / RxSwift Native app有很大一部分的时间是在等待事件发生,然后响应事件,比如 1.等待网络请求完成, 2.等待用户的操作, 3.等待 ...
- RxSwift之路 1#Swift语法知识准备
RxSwift之路 1#Swift语法知识准备 在开始学习 RxSwift 之前,一定要对 Swift 相关语法有所了解,否则就很难理解为什么可以这样.关于 Swift 的学习其实只要看看 Swift ...
- Functor、Applicative 和 Monad(重要)
Functor.Applicative 和 Monad Posted by 雷纯锋Nov 8th, 2015 10:53 am Functor.Applicative 和 Monad 是函数式编程语言 ...
- ReactiveCocoa入门教程:第一部分
http://www.cocoachina.com/ios/20150123/10994.html 本文翻译自RayWenderlich,原文:ReactiveCocoa Tutorial--The ...
- 使用ReactiveCocoa实现iOS平台响应式编程
使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍一下FRP(Functional Reactive Prog ...
- [转]使用ReactiveCocoa实现iOS平台响应式编程
原文:http://www.itiger.me/?p=38 使用ReactiveCocoa实现iOS平台响应式编程 ReactiveCocoa和响应式编程 在说ReactiveCocoa之前,先要介绍 ...
- Scalaz(28)- ST Monad :FP方式适用变量
函数式编程模式强调纯代码(pure code),主要实现方式是使用不可变数据结构,目的是函数组合(composability)最终实现函数组件的重复使用.但是,如果我们在一个函数p内部使用了可变量(m ...
- FRP represents an intersection of two programming paradigms.
FRP represents an intersection of two programming paradigms. Functional programming Functional progr ...
- iOS Architecture Patterns
By Bohdan Orlov on 21 Mar 2016 - 0 Comments iOS FYI: Slides from my presentation at NSLondon are ava ...
随机推荐
- bzoj 5369: [Pkusc2018]最大前缀和
Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...
- MySQL 字段全部转换成小写
原因: 因为框架某些字段大写有时候不被正确识别,所以字段都修改成小写; 特别说明:因为这里只有表,没有视图,存储过程等等其它所以我可以直接这么写; 步骤: 1.导出结构语句 2. 执行C# 脚本,替换 ...
- Silverlight & Blend动画设计系列八:拖放(Drag-Drop)操作与拖放行为(DragBehavior)
在Silverlight中自身并没有提供拖放功能的相关实现,要实现拖放功能得借助其事件支持(MouseLeftButtonDown.MouseLeftButtonUp和MouseMove)来完成,实际 ...
- type=file的change事件只能执行一次的解决方案
最近帮朋友做个项目中遇到了type=file change事件只能执行一次的问题,度娘了一下,发现提供了各种解决方案,所以决定记录一下我的思考方向和最终解决方式. 起初帮朋友做个项目,项目中遇到上传文 ...
- 二:Nexus知识
Nexus访问 Http://localhost:8080/nexus Nexus登陆 用户:admin 密码:admin123 Nexus仓库 nexus的仓库类型分为以下四种: group: 仓库 ...
- input的属性用法介绍
Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text,这是我们见的 ...
- springMVC介绍及配置
Spring MVC的Controller用于处理用户的请求.Controller相当于Struts 1里的Action,他们的实现机制.运行原理都类似. Controller是个接口,一般直接继承A ...
- Web前端面试指导(十七):一个满屏 品 字布局 如何设计?
题目点评 这道题目有可能是笔试题,有可能面谈的时候进行叙述,如果是笔试题要求对css样式代码非常熟练,如果是面谈叙述,就需要你的表达能力非常强,要抓住要点,把需要用到的技能点讲清楚就可以了. 需要用到 ...
- 在Datagridview中添加datagridviewComboBox列并显示下拉列表
在DataGridView中自动的添加Column. private void button_autoAddColumn_Click(object sender, EventArgs e) { try ...
- IDEA maven 多项目 出现 java 程序包找不到
使用idea 多项目引入的时候,出现报错信息:Error java程序包找不到 解决办法: 我在引入多个项目的时候,他们是在一个目录里面的.我把整个目录引入了进去.结果报依赖包找不到. 把引入的全部项 ...