Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Alexander Voronov
Search
Oleksandr Voronov
September 15, 2015
Programming
2
1.2k
Alexander Voronov
Swift: Going Functional
https://youtu.be/Dc9aKhs37BE
Oleksandr Voronov
September 15, 2015
Tweet
Share
More Decks by Oleksandr Voronov
See All by Oleksandr Voronov
Controllable Randomness in Unit Tests
alexandervoronov
1
47
Modularizing your iOS apps
alexandervoronov
0
130
TDD in Real World
alexandervoronov
1
220
Building CLI with Swift
alexandervoronov
1
320
Stanfy MadCode 10: From Java to Kotlin, from Objective-C to Swift
alexandervoronov
0
230
ReactiveCocoa
alexandervoronov
0
150
Other Decks in Programming
See All in Programming
F#で自在につくる静的ブログサイト - 関数型まつり2025
pizzacat83
0
310
技術懸念に立ち向かい 法改正を穏便に乗り切った話
pop_cashew
0
1.5k
ドメインモデリングにおける抽象の役割、tagless-finalによるDSL構築、そして型安全な最適化
knih
11
1.9k
単体テストの始め方/作り方
toms74209200
0
510
つよそうにふるまい、つよい成果を出すのなら、つよいのかもしれない
irof
1
290
Enterprise Web App. Development (2): Version Control Tool Training Ver. 5.1
knakagawa
1
120
イベントストーミングから始めるドメイン駆動設計
jgeem
4
870
XSLTで作るBrainfuck処理系
makki_d
0
210
Elixir で IoT 開発、 Nerves なら簡単にできる!?
pojiro
1
150
関数型まつり2025登壇資料「関数プログラミングと再帰」
taisontsukada
2
840
今ならAmazon ECSのサービス間通信をどう選ぶか / Selection of ECS Interservice Communication 2025
tkikuc
11
2.7k
Claude Codeの使い方
ttnyt8701
1
130
Featured
See All Featured
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
3k
Product Roadmaps are Hard
iamctodd
PRO
53
11k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
The World Runs on Bad Software
bkeepers
PRO
68
11k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Building an army of robots
kneath
306
45k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
29
1.8k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
790
How to Ace a Technical Interview
jacobian
277
23k
RailsConf 2023
tenderlove
30
1.1k
A Tale of Four Properties
chriscoyier
159
23k
Transcript
Swift Rocks 2! Alexander Voronov iOS Developer @ Stanfy
Swift Going Functional
What is Functional Programming?
Functional Programming
Functional Programming • Higher-order functions
Functional Programming • Higher-order functions • Immutable states & pure
functions
Functional Programming • Higher-order functions • Immutable states & pure
functions • Modularity
Functional Programming • Higher-order functions • Immutable states & pure
functions • Modularity • Types
Swift Power
Swift Power
Swift Power • First Class Functions
Swift Power • First Class Functions • Currying
Swift Power • First Class Functions • Currying • Generics
Swift Power • First Class Functions • Currying • Generics
• Type Inference
Swift Power • First Class Functions • Currying • Generics
• Type Inference • Enums
First Class Functions func add(x: Int) -> Int -> Int
{ return { y in y + x } } let addOne = add(1) addOne(2) // 3
First Class Functions func addTwo(x: Int) -> Int { return
x + 2 } (1...5).map(addTwo) // [3, 4, 5, 6, 7]
Currying func add(a: Int)(b: Int) -> Int { return a
+ b } let addOne = add(1) let xs = 1...5 xs.map(addOne) // [2, 3, 4, 5, 6]
Currying func curry<A, B, C>(f: (A, B) -> C) ->
A -> B -> C { return { a in { b in f(a, b) } } }
Generics func printEach<T: SequenceType>(items: T) { for item in items
{ print(item) } } printEach(1...5) printEach(["one", "two", "three"])
Type Inference let x = 42.0 x.dynamicType // Double x
is Double // true
Type Inference var xs = [1, 5, 2, 4, 3]
xs.sort(<) print(xs) // [1, 2, 3, 4, 5]
Type Inference var xs = [1, 5, 2, 4, 3]
xs.sort(<) print(xs) // [1, 2, 3, 4, 5]
Type Inference let xs = [1, 5, 2, 4, 3]
let ys = xs.sorted(<) print(xs) // [1, 5, 2, 4, 3] print(ys) // [1, 2, 3, 4, 5]
Type Inference let xs = [1, 5, 2, 4, 3]
let ys = xs.sorted(<) print(xs) // [1, 5, 2, 4, 3] print(ys) // [1, 2, 3, 4, 5]
Enumerations enum Fruit: String { case Apple = "apple" case
Banana = "banana" case Cherry = "cherry" } Fruit.Apple.rawValue // "apple"
Enumerations enum ValidationResult { case Valid case NotValid(NSError) }
Enumerations enum MyApi { case xAuth(String, String) case GetUser(Int) }
extension MyApi: MoyaTarget { var baseURL: NSURL { return NSURL(string: "")! } var path: String { switch self { case .xAuth: return "/authorise" case .GetUser(let id): return "/user/\(id)" } } } https://github.com/Moya/Moya
Optionals enum Optional<T> { case None case Some(T) } var
x = 5 x = nil // Error!
Optional Chaining struct Dog { var name: String } struct
Person { var dog: Dog? } let dog = Dog(name: "Dodge") let person = Person(dog: dog) let dogName = person.dog?.name
Optional Chaining struct Dog { var name: String } struct
Person { var dog: Dog? } let dog = Dog(name: "Dodge") let person = Person(dog: dog) let dogName = person.dog?.name Optional Chaining
Functors, Applicatives, Monads
None
Functors, Applicatives, Monads let x = 2 x + 3
// == 5
Functors, Applicatives, Monads let x = 2 x + 3
// == 5 let y = Optional(2)
Functors let y = Optional(2) y + 3 // Error!
// Value of optional type // Optional<Int> not unwrapped
Functors let y = Optional(2) y.map { $0 + 3
} // Optional(5)
Functors func map<U>(f: T -> U) -> U? { switch
self { case .Some(let x): return f(x) case .None: return .None } }
Functors infix operator <^> { associativity left } func <^><T,
U>(f: T -> U, a: T?) -> U? { return a.map(f) }
Functors func <^><T, U>(f: T -> U, a: T?) ->
U? { return a.map(f) } let addOne = { $0 + 1 } addOne <^> Optional(2) // Optional(3)
Applicative func apply<U>(f: (T -> U)?) -> U? { switch
f { case .Some(let someF): return self.map(someF) case .None: return .None } }
Applicatives infix operator <*> { associativity left } func <*><T,
U>(f: (T -> U)?, a: T?) -> U? { return a.apply(f) }
Applicatives infix operator <*> { associativity left } func <*><T,
U>(f: (T -> U)?, a: T?) -> U? { return a.apply(f) } func add(a: Int)(b: Int) -> Int { return a + b }
Applicatives add <^> Optional(2) <*> Optional(3) // Optional(5)
Applicatives add <^> Optional(2) <*> Optional(3) // Optional(5)
Applicatives add <^> Optional(2) <*> Optional(3) // Optional(5) let a
= add <^> Optional(2)
Applicatives add <^> Optional(2) <*> Optional(3) // Optional(5) let a
= add <^> Optional(2)
Applicatives add <^> Optional(2) <*> Optional(3) // Optional(5) let a
= add <^> Optional(2) let a: (b: Int) -> Int?
Monads typealias T = Double let f: T -> T
= { $0 * 2.0 } let g: (T, T) -> T = { $0 / $1 }
Monads typealias T = Double let f: T -> T
= { $0 * 2.0 } let g: (T, T) -> T = { $0 / $1 } f(g(4, 2))
Monads typealias T = Double let f: T -> T
= { $0 * 2.0 } let g: (T, T) -> T = { $0 / $1 } f(g(4, 2)) g: (T, T) -> T?
Monads typealias T = Double let f: T -> T
= { $0 * 2.0 } let g: (T, T) -> T = { $0 / $1 } f(g(4, 2)) g: (T, T) -> T? g(4, 2) >>- { f($0) }
Monads >>- == http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
Monads func flatten<U>(a: U??) -> U? { switch a {
case .Some(let someA): return someA case .None: return .None } }
Monads func flatMap<U>(f: T -> U?) -> U? { return
flatten(map(f)) }
Monads func flatMap<U>(f: T -> U?) -> U? { return
flatten(map(f)) } func map<U>(f: T -> U) -> U?
Monads func flatMap<U>(f: T -> U?) -> U? { return
flatten(map(f)) } func map<U>(f: T -> U) -> U?
Monads func flatMap<U>(f: T -> U?) -> U? { return
flatten(map(f)) } func map<U>(f: T -> U) -> U? func map<U?>(f: T -> U?) -> U??
Monads infix operator >>- { associativity left } func >>-<T,
U>(a: T?, f: T -> U?) -> U? { return a.flatMap(f) }
Monads func half(a: Int) -> Int? { return a %
2 == 0 ? a / 2 : .None }
Monads func half(a: Int) -> Int? { return a %
2 == 0 ? a / 2 : .None } Optional(8) >>- half >>- half // Optional(2)
Monad Laws • Left Identity • Right Identity • Associativity
Left Identity Law let f = { Optional($0 + 1)
} let a = 1 let x = Optional(a) >>- f let y = f(a) x == y
Right Identity Law func create<T>(value: T) -> T? { return
Optional(value) } let x = Optional(1) >>- create let y = Optional(1) x == y
Associativity Law let double = { Optional(2 * $0) }
let triple = { Optional(3 * $0) } let x = Optional(1) >>- double >>- triple let y = Optional(1) >>- { double($0) >>- triple } let z = { Optional(1) >>- double }() >>- triple x == y y == z
Recap Functor map<U>(f: T -> U) -> M<U> Applicative apply<U>(f:
M<(T -> U)>) -> M<U> Monad flatMap<U>(f: T -> M<U>) -> M<U>
Pipes & Railways @ScottWlaschin
Pipes infix operator |> { associativity left } public func
|> <T, U>(x: T, f: T -> U) -> U { return f(x) } let addTwo = { $0 + 2 } let prodThree = { $0 * 3 } 5 |> addTwo |> prodThree |> print // 21
Pipes let transformedX = x |> addTwo |> prodThree |>
increment |> square |> pow VS (pow(square(increment(prodThree(addTwo(x))))))
Railways http://fsharpforfunandprofit.com/posts/recipe-part2/
Argo JSON Parser + Argo Runes
Argo Example extension Model: Decodable { static func decode(json: JSON)
-> Decoded<Model> { return Model.create <^> json <| "id" <*> json <| "room" <*> json <| "guest_name" <*> json <| "status" <*> json <| "label" <*> json <|? "user_comment" <*> json <| ["channel", "label"] <*> json <| "severity" <*> json <|| "epochs" <*> json <|| "body" } }
Argo Example let entities: [Model]? entities = data?.json() >>- {
$0["entities"] } >>- decode
Where Next?
Where Next • Functors, Applicatives and Monads in Pictures •
Railway Oriented Programming • Functional Programming in Swift (Objc.io) • Argo • Swiftz • RxSwift • ReactiveCocoa-3.0 • Haskell, F#, Erlang, Elm
Thanks!
Comments / Questions? @aleks_voronov a-voronov