SlideShare a Scribd company logo
How to use Functional
Reactive Programming
without Black Magic
let me = Person(name: "Jens Ravens")
@JensRavens
GitHub: JensRavens
nerdgeschoss.de
swift.berlin
A short introduction to
functional programming, the
universe and everything.
In the beginning McIlroy
created the unix pipe. And he
saw it was good.
ls | grep *.jpg | sort
Application Architecture
Functional Reactive Programming without Black Magic (UIKonf 2015)
starting from a blank slate
implement to understand
And I promise not to use the
scary M-word.
me, 12 weeks ago.
How to train
your monad.
–Saunders Mac Lane
All told, a monad is just a monoid in the
category of endofunctors.
“
Monads are just Applicative Functors
“
ls | grep *.jpg | sort
Buy it, use it,
break it, fix it,
Trash it, change it,
mail - upgrade it.
– Daft Punk, Technologic
Buy it;
if error {
//TODO: Handle me!
} else {
use it;
if error {
//TODO: Handle me!
} else {
break it;
if error {
//TODO: Handle me!
ls | grep *.jpg | sort
Monad
something that defines map and bind
The optional Monad
let string: String? = "World"
let greeting = string.map{"Hello ($0)”}
//Hello World
extension Optional {
func bind<U> (f: T->U?) -> U? {
if let result = self.map({f($0)}) {
return result
} else {
return nil
}
}
}
The optional Monad
let string: String? = "World"
let greeting = string.map{"Hello ($0)”}
//Hello World
func greetOrNil(name: String)->String? {
if name == "World" {
return "Hello World"
} else {
return nil
}
}
let greeting2 = string.bind(greetOrNil)
//Hello World
The optional Monad
extension Optional {
func bind<U> (f: T->U?) -> U? {
if let result = self.map({f($0)}) {
return result
} else {
return nil
}
}
}
extension Optional {
func bind<U> (f: T->Optional<U>) -> Optional<U> {
switch self {
case let .Some(value): return f(value)
case .None: return nil
}
}
}
The result Monad
public enum Result<T> {
case Success(Box<T>)
case Error(NSError)
}
The result Monad
public enum Result<T> {
…
public func map<U>(f: T -> U) -> Result<U> {
switch self {
case let .Success(v):
return .Success(Box(f(v.value)))
case let .Error(error): return .Error(error)
}
}
…
}
The result Monad
public enum Result<T> {
…
public func bind<U>(f: T -> Result<U>)
-> Result<U> {
switch self {
case let .Success(v): return f(v.value)
case let .Error(error): return .Error(error)
}
}
…
}
ls | grep *.jpg | sort
Monad
Transform
func parseString(data: NSData) ->
Result<String>
func parseJson(data: NSData) ->
Result<[String: AnyObject]>
func asyncGreeting(name: String,
completion: Result<String>->Void)
public func bind<U>(f:(T, (Result<U>->Void))->Void)
-> (Result<U>->Void)->Void {
return { g in
switch self {
case let .Success(v): f(v.value, g)
case let .Error(error): g(.Error(error))
}
}
}
Interstellar
ls | grep *.jpg | sort
public final class Signal<T> {
private var value: Result<T>?
private var callbacks: [Result<T> -> Void] = []
public func subscribe(f: Result<T> -> Void) {
if let value = value {
f(value)
}
callbacks.append(f)
}
public func update(value: Result<T>) {
self.value = value
self.callbacks.map{$0(value)}
}
}
public func map<U>(f: T -> U) -> Signal<U> {
let signal = Signal<U>()
subscribe { result in
signal.update(result.map(f))
}
return signal
}
public func bind<U>(f: T -> Result<U>) -> Signal<U> {
let signal = Signal<U>()
subscribe { result in
signal.update(result.bind(f))
}
return signal
}
public func bind<U>(f: (T, (Result<U>->Void))->Void)
-> Signal<U> {
let signal = Signal<U>()
subscribe { value in
value.bind(f)(signal.update)
}
return signal
}
pushing instead of pulling
the rise of custom
operators
infix operator >>> { associativity left precedence 160 }
public func >>> <A,B> (left: Signal<A>,
right: A->Result<B>) -> Signal<B> {
return left.bind(right)
}
public func >>> <A,B>(left: Signal<A>,
right: (A, (Result<B>->Void))->Void) -> Signal<B>{
return left.bind(right)
}
public func >>> <A,B> (left: Signal<A>, right: A->B) ->
Signal<B> {
return left.map(right)
}
ls | grep *.jpg | sort
ls | grep *.jpg | sort
ls >>> grep("*.jpg") >>> sort
But what about
Threads?
public final class Thread {
public static func main<T>(a: T, completion:
T->Void) {
dispatch_async(dispatch_get_main_queue())
{
completion(a)
}
}
public static func background<T>(queue:
dispatch_queue_t)(_ a: T, _ completion: T->Void)
{
dispatch_async(queue){
completion(a)
}
}
}
ls >>> Thread.background(queue) >>> grep("*.jpg")
>>> sort >>> Thread.main
Extending UIKit to
support Signals.
var SignalHandle: UInt8 = 0
extension UITextField {
public var textSignal: Signal<String> {
let signal: Signal<String>
if let handle = objc_getAssociatedObject(self,
&SignalHandle) as? Signal<String> {
signal = handle
} else {
signal = Signal("")
NSNotificationCenter.defaultCenter().addObserver(self,
selector: Selector("textChanged:"), name:
UITextFieldTextDidChangeNotification, object: self)
objc_setAssociatedObject(self, &SignalHandle,
signal,
objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
}
return signal
}
public func textChanged(notification: NSNotification) {
textSignal.update(.Success(Box(self.text)))
}
}
If it’s variable, it qualifies
as a Signal.
ReactiveKitten
It’s about gifs. And cats.
And gifs of cats.
userTyping >>> createURL >>> loadRequest
>>> parseData >>> mainThread >>>
displayCats
The transform, the cat
and you.
import Interstellar
private func request(path: String, completion: Result<NSData>->Void)
{
let url = NSURL(string: baseURL.stringByAppendingString(path))!
let request = NSURLRequest(URL: url)
session.dataTaskWithRequest(request){ data, response, error in
if error != nil {
completion(.Error(error))
} else if let response = response as? NSHTTPURLResponse {
if response.statusCode >= 200 && response.statusCode<300 {
completion(.Success(Box(data)))
} else {
completion(.Error(NSError(domain: "Networking", code:
response.statusCode, userInfo: nil)))
}
} else {
completion(.Error(NSError(domain: "Networking", code: 500,
userInfo: nil)))
}
}.resume()
}
private func parseJSON(data: NSData)
->Result<[String: AnyObject]> {
var error: NSError?
if let json =
NSJSONSerialization.JSONObjectWithData(data, options:
nil, error: &error) as? [String: AnyObject] {
return .Success(Box(json))
} else {
return .Error(error!)
}
}
let imageSignal = gifSignal >>> getURL >>>
Thread.background >>> loadFromCache >>>
retryFromNetwork >>> Thread.main
class ViewController: UIViewController {
var signal: Signal<[Gif]>!
let searchBar = UISearchBar()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = searchBar
signal = searchBar.textSignal >>>
Network().search() >>> Thread.main
github.com/jensravens/reactivekitten
What’s next()?
Functors, Applicatives
and Monads in Pictures.
http://adit.io/posts/2013-04-17-
functors,_applicatives,_and_monads_in_pictures.html
The Introduction to RP
you’ve been missing.
https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
ReactiveCocoa 3
RxSwift
Interstellar
available on Carthage
jensravens/interstellar
Thank you.
@JensRavens
github.com/jensravens/interstellar

More Related Content

What's hot (20)

PPT
ECMAScript 6: A Better JavaScript for the Ambient Computing Era
Allen Wirfs-Brock
 
PDF
Voxxed Days Vilnius 2015 - Having fun with Javassist
Anton Arhipov
 
PDF
Introduction to Elm
Rogerio Chaves
 
PPTX
Avoiding Callback Hell with Async.js
cacois
 
PPT
A Deeper look into Javascript Basics
Mindfire Solutions
 
PDF
An Introduction to Reactive Cocoa
SmartLogic
 
ODP
Lambda Chops - Recipes for Simpler, More Expressive Code
Ian Robertson
 
PPT
JavaScript Basics
Mats Bryntse
 
PDF
Lambdas and Streams Master Class Part 2
José Paumard
 
PDF
50 new things we can do with Java 8
José Paumard
 
PDF
Building Hermetic Systems (without Docker)
William Farrell
 
PDF
JavaScript in 2016
Codemotion
 
PDF
Elm kyivfprog 2015
Alexander Mostovenko
 
PDF
How much performance can you get out of Javascript? - Massimiliano Mantione -...
Codemotion
 
PPSX
JS Fest 2018. Сергей Пузанков. E2E-тестирование фронтенда c Hermione
JSFestUA
 
ODP
Migrations With Transmogrifier
Rok Garbas
 
PDF
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
PDF
Lambda and Stream Master class - part 1
José Paumard
 
PPTX
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
PDF
Core Java - Quiz Questions - Bug Hunt
CodeOps Technologies LLP
 
ECMAScript 6: A Better JavaScript for the Ambient Computing Era
Allen Wirfs-Brock
 
Voxxed Days Vilnius 2015 - Having fun with Javassist
Anton Arhipov
 
Introduction to Elm
Rogerio Chaves
 
Avoiding Callback Hell with Async.js
cacois
 
A Deeper look into Javascript Basics
Mindfire Solutions
 
An Introduction to Reactive Cocoa
SmartLogic
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Ian Robertson
 
JavaScript Basics
Mats Bryntse
 
Lambdas and Streams Master Class Part 2
José Paumard
 
50 new things we can do with Java 8
José Paumard
 
Building Hermetic Systems (without Docker)
William Farrell
 
JavaScript in 2016
Codemotion
 
Elm kyivfprog 2015
Alexander Mostovenko
 
How much performance can you get out of Javascript? - Massimiliano Mantione -...
Codemotion
 
JS Fest 2018. Сергей Пузанков. E2E-тестирование фронтенда c Hermione
JSFestUA
 
Migrations With Transmogrifier
Rok Garbas
 
Introduction to reactive programming & ReactiveCocoa
Florent Pillet
 
Lambda and Stream Master class - part 1
José Paumard
 
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
Core Java - Quiz Questions - Bug Hunt
CodeOps Technologies LLP
 

Similar to Functional Reactive Programming without Black Magic (UIKonf 2015) (20)

PDF
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Codemotion
 
PDF
Taming Asynchronous Transforms with Interstellar
Jens Ravens
 
KEY
Beauty and Power of Go
Frank Müller
 
PPTX
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 
PDF
Monads in Swift
Vincent Pradeilles
 
PDF
[Codemotion 2015] patrones de diseño con java8
Alonso Torres
 
PPTX
F# Presentation for SmartDevs, Hereford
Kit Eason
 
PDF
Go ahead, make my day
Tor Ivry
 
PPTX
Deep Learning, Scala, and Spark
Oswald Campesato
 
PPTX
Advanced #2 threading
Vitali Pekelis
 
PDF
Functional Programming You Already Know
Kevlin Henney
 
PPTX
functions
Makwana Bhavesh
 
PDF
От Java Threads к лямбдам, Андрей Родионов
Yandex
 
PDF
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron
 
PDF
Spark 4th Meetup Londond - Building a Product with Spark
samthemonad
 
PDF
Kotlin Bytecode Generation and Runtime Performance
intelliyole
 
PDF
Introduction to functional programming using Ocaml
pramode_ce
 
PDF
Wien15 java8
Jaanus Pöial
 
PDF
Java 8 new features or the ones you might actually use
Sharon Rozinsky
 
DOCX
Fractal proj report 2
rpiitcbme
 
Functional Programming You Already Know - Kevlin Henney - Codemotion Rome 2015
Codemotion
 
Taming Asynchronous Transforms with Interstellar
Jens Ravens
 
Beauty and Power of Go
Frank Müller
 
Столпы функционального программирования для адептов ООП, Николай Мозговой
Sigma Software
 
Monads in Swift
Vincent Pradeilles
 
[Codemotion 2015] patrones de diseño con java8
Alonso Torres
 
F# Presentation for SmartDevs, Hereford
Kit Eason
 
Go ahead, make my day
Tor Ivry
 
Deep Learning, Scala, and Spark
Oswald Campesato
 
Advanced #2 threading
Vitali Pekelis
 
Functional Programming You Already Know
Kevlin Henney
 
functions
Makwana Bhavesh
 
От Java Threads к лямбдам, Андрей Родионов
Yandex
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
Pavlo Baron
 
Spark 4th Meetup Londond - Building a Product with Spark
samthemonad
 
Kotlin Bytecode Generation and Runtime Performance
intelliyole
 
Introduction to functional programming using Ocaml
pramode_ce
 
Wien15 java8
Jaanus Pöial
 
Java 8 new features or the ones you might actually use
Sharon Rozinsky
 
Fractal proj report 2
rpiitcbme
 
Ad

More from Jens Ravens (7)

PDF
Turning it up to 11 - Scaling Ruby on Rails to 100k rps
Jens Ravens
 
PDF
Server Side Swift - AppBuilders 2017
Jens Ravens
 
PDF
Server Side Swift
Jens Ravens
 
PDF
Working with Xcode and Swift Package Manager
Jens Ravens
 
PDF
Server Side Swift with Swag
Jens Ravens
 
PDF
Swift 2
Jens Ravens
 
PDF
Swift: Immutability and You
Jens Ravens
 
Turning it up to 11 - Scaling Ruby on Rails to 100k rps
Jens Ravens
 
Server Side Swift - AppBuilders 2017
Jens Ravens
 
Server Side Swift
Jens Ravens
 
Working with Xcode and Swift Package Manager
Jens Ravens
 
Server Side Swift with Swag
Jens Ravens
 
Swift 2
Jens Ravens
 
Swift: Immutability and You
Jens Ravens
 
Ad

Recently uploaded (20)

PDF
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PDF
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PPTX
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
PPTX
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
PDF
Understanding the Need for Systemic Change in Open Source Through Intersectio...
Imma Valls Bernaus
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
PDF
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Odoo CRM vs Zoho CRM: Honest Comparison 2025
Odiware Technologies Private Limited
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
SAP Firmaya İade ABAB Kodları - ABAB ile yazılmıl hazır kod örneği
Salih Küçük
 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
SciPy 2025 - Packaging a Scientific Python Project
Henry Schreiner
 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Coefficient of Variance in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pptx
Varsha Nayak
 
Understanding the Need for Systemic Change in Open Source Through Intersectio...
Imma Valls Bernaus
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
Beyond Binaries: Understanding Diversity and Allyship in a Global Workplace -...
Imma Valls Bernaus
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 

Functional Reactive Programming without Black Magic (UIKonf 2015)

  • 1. How to use Functional Reactive Programming without Black Magic
  • 2. let me = Person(name: "Jens Ravens") @JensRavens GitHub: JensRavens nerdgeschoss.de swift.berlin
  • 3. A short introduction to functional programming, the universe and everything.
  • 4. In the beginning McIlroy created the unix pipe. And he saw it was good. ls | grep *.jpg | sort
  • 7. starting from a blank slate
  • 9. And I promise not to use the scary M-word. me, 12 weeks ago.
  • 11. –Saunders Mac Lane All told, a monad is just a monoid in the category of endofunctors. “
  • 12. Monads are just Applicative Functors “
  • 13. ls | grep *.jpg | sort
  • 14. Buy it, use it, break it, fix it, Trash it, change it, mail - upgrade it. – Daft Punk, Technologic
  • 15. Buy it; if error { //TODO: Handle me! } else { use it; if error { //TODO: Handle me! } else { break it; if error { //TODO: Handle me!
  • 16. ls | grep *.jpg | sort
  • 18. The optional Monad let string: String? = "World" let greeting = string.map{"Hello ($0)”} //Hello World extension Optional { func bind<U> (f: T->U?) -> U? { if let result = self.map({f($0)}) { return result } else { return nil } } }
  • 19. The optional Monad let string: String? = "World" let greeting = string.map{"Hello ($0)”} //Hello World func greetOrNil(name: String)->String? { if name == "World" { return "Hello World" } else { return nil } } let greeting2 = string.bind(greetOrNil) //Hello World
  • 20. The optional Monad extension Optional { func bind<U> (f: T->U?) -> U? { if let result = self.map({f($0)}) { return result } else { return nil } } } extension Optional { func bind<U> (f: T->Optional<U>) -> Optional<U> { switch self { case let .Some(value): return f(value) case .None: return nil } } }
  • 21. The result Monad public enum Result<T> { case Success(Box<T>) case Error(NSError) }
  • 22. The result Monad public enum Result<T> { … public func map<U>(f: T -> U) -> Result<U> { switch self { case let .Success(v): return .Success(Box(f(v.value))) case let .Error(error): return .Error(error) } } … }
  • 23. The result Monad public enum Result<T> { … public func bind<U>(f: T -> Result<U>) -> Result<U> { switch self { case let .Success(v): return f(v.value) case let .Error(error): return .Error(error) } } … }
  • 24. ls | grep *.jpg | sort Monad Transform
  • 25. func parseString(data: NSData) -> Result<String> func parseJson(data: NSData) -> Result<[String: AnyObject]> func asyncGreeting(name: String, completion: Result<String>->Void)
  • 26. public func bind<U>(f:(T, (Result<U>->Void))->Void) -> (Result<U>->Void)->Void { return { g in switch self { case let .Success(v): f(v.value, g) case let .Error(error): g(.Error(error)) } } }
  • 28. ls | grep *.jpg | sort
  • 29. public final class Signal<T> { private var value: Result<T>? private var callbacks: [Result<T> -> Void] = [] public func subscribe(f: Result<T> -> Void) { if let value = value { f(value) } callbacks.append(f) } public func update(value: Result<T>) { self.value = value self.callbacks.map{$0(value)} } }
  • 30. public func map<U>(f: T -> U) -> Signal<U> { let signal = Signal<U>() subscribe { result in signal.update(result.map(f)) } return signal } public func bind<U>(f: T -> Result<U>) -> Signal<U> { let signal = Signal<U>() subscribe { result in signal.update(result.bind(f)) } return signal }
  • 31. public func bind<U>(f: (T, (Result<U>->Void))->Void) -> Signal<U> { let signal = Signal<U>() subscribe { value in value.bind(f)(signal.update) } return signal }
  • 33. the rise of custom operators
  • 34. infix operator >>> { associativity left precedence 160 } public func >>> <A,B> (left: Signal<A>, right: A->Result<B>) -> Signal<B> { return left.bind(right) } public func >>> <A,B>(left: Signal<A>, right: (A, (Result<B>->Void))->Void) -> Signal<B>{ return left.bind(right) } public func >>> <A,B> (left: Signal<A>, right: A->B) -> Signal<B> { return left.map(right) }
  • 35. ls | grep *.jpg | sort
  • 36. ls | grep *.jpg | sort ls >>> grep("*.jpg") >>> sort
  • 38. public final class Thread { public static func main<T>(a: T, completion: T->Void) { dispatch_async(dispatch_get_main_queue()) { completion(a) } } public static func background<T>(queue: dispatch_queue_t)(_ a: T, _ completion: T->Void) { dispatch_async(queue){ completion(a) } } } ls >>> Thread.background(queue) >>> grep("*.jpg") >>> sort >>> Thread.main
  • 40. var SignalHandle: UInt8 = 0 extension UITextField { public var textSignal: Signal<String> { let signal: Signal<String> if let handle = objc_getAssociatedObject(self, &SignalHandle) as? Signal<String> { signal = handle } else { signal = Signal("") NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("textChanged:"), name: UITextFieldTextDidChangeNotification, object: self) objc_setAssociatedObject(self, &SignalHandle, signal, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) } return signal } public func textChanged(notification: NSNotification) { textSignal.update(.Success(Box(self.text))) } }
  • 41. If it’s variable, it qualifies as a Signal.
  • 42. ReactiveKitten It’s about gifs. And cats. And gifs of cats.
  • 43. userTyping >>> createURL >>> loadRequest >>> parseData >>> mainThread >>> displayCats The transform, the cat and you.
  • 44. import Interstellar private func request(path: String, completion: Result<NSData>->Void) { let url = NSURL(string: baseURL.stringByAppendingString(path))! let request = NSURLRequest(URL: url) session.dataTaskWithRequest(request){ data, response, error in if error != nil { completion(.Error(error)) } else if let response = response as? NSHTTPURLResponse { if response.statusCode >= 200 && response.statusCode<300 { completion(.Success(Box(data))) } else { completion(.Error(NSError(domain: "Networking", code: response.statusCode, userInfo: nil))) } } else { completion(.Error(NSError(domain: "Networking", code: 500, userInfo: nil))) } }.resume() }
  • 45. private func parseJSON(data: NSData) ->Result<[String: AnyObject]> { var error: NSError? if let json = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? [String: AnyObject] { return .Success(Box(json)) } else { return .Error(error!) } }
  • 46. let imageSignal = gifSignal >>> getURL >>> Thread.background >>> loadFromCache >>> retryFromNetwork >>> Thread.main
  • 47. class ViewController: UIViewController { var signal: Signal<[Gif]>! let searchBar = UISearchBar() override func viewDidLoad() { super.viewDidLoad() navigationItem.titleView = searchBar signal = searchBar.textSignal >>> Network().search() >>> Thread.main
  • 50. Functors, Applicatives and Monads in Pictures. http://adit.io/posts/2013-04-17- functors,_applicatives,_and_monads_in_pictures.html
  • 51. The Introduction to RP you’ve been missing. https://gist.github.com/staltz/868e7e9bc2a7b8c1f754