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
Functional Programming Practice in Swift
Search
Hank Bao
January 10, 2016
Programming
4
110
Functional Programming Practice in Swift
Swift 函数式编程实践
2016年1月10日在 @Swift 大会上的分享
Hank Bao
January 10, 2016
Tweet
Share
More Decks by Hank Bao
See All by Hank Bao
Notes on Gamification
hankbao
0
120
Reverse Engineering: from Objective-C to Swift
hankbao
2
430
Type-safe Programming Practice in Swift
hankbao
0
110
Other Decks in Programming
See All in Programming
List Unfolding - 'unfold' as the Computational Dual of 'fold', and how 'unfold' relates to 'iterate'"
philipschwarz
PRO
0
150
Rethinking Data Access: The New httpResource in Angular
manfredsteyer
PRO
0
220
💎 My RubyKaigi Effect in 2025: Top Ruby Companies 🌐
yasulab
PRO
1
130
技術的負債と戦略的に戦わざるを得ない場合のオブザーバビリティ活用術 / Leveraging Observability When Strategically Dealing with Technical Debt
yoshiyoshifujii
0
170
単体テストの始め方/作り方
toms74209200
0
250
AI Coding Agent Enablement in TypeScript
yukukotani
17
7.4k
複数アプリケーションを育てていくための共通化戦略
irof
7
3.1k
がんばりすぎないコーディングルール運用術
tsukakei
1
200
Passkeys for Java Developers
ynojima
2
680
Efficiency and Rock 'n’ Roll (Really!)
hollycummins
0
620
Feature Flag 自動お掃除のための TypeScript プログラム変換
azrsh
PRO
4
650
プロダクト改善のために新しいことを始める -useContextからの卒業、Zustandへ-
rebase_engineering
1
100
Featured
See All Featured
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
45
7.3k
Building an army of robots
kneath
306
45k
Designing for Performance
lara
608
69k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
25
2.8k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
How to Think Like a Performance Engineer
csswizardry
23
1.6k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.3k
It's Worth the Effort
3n
184
28k
Designing for humans not robots
tammielis
253
25k
Practical Orchestrator
shlominoach
188
11k
How GitHub (no longer) Works
holman
314
140k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
50k
Transcript
SWIFT ڍහୗᖫᑕ ਫ᪢
@HANKBAO ᅀIM
WHAT
WHAT Functional programming is a programming paradigm 1. treats computation
as the evaluation of mathematical functions 2. avoids changing-state and mutable data — Wikipedia
PARADIGM
None
THINK
IMPERATIVE: MACHINE let nums = [1, 2, 3, 4, 5,
6, 7] var strs = [String]() for var i = 0; i < nums.count; ++i { strs.append(String(nums[i])) }
DECLARATIVE: MATHEMATICS let nums = [1, 2, 3, 4, 5,
6, 7] let strs = nums.map(String.init)
WHY
CURRY
CURRY func x(a: A, b: B, c: C) -> E
func x(a: A) -> (b: B) -> (c: C) -> E
CURRY struct User { func login(password: String) } let passwd
= "@Swift" let usr = User() usr.login(passwd)
CURRY struct User { func login(password: String) } let passwd
= "@Swift" let usr = User() User.login(usr)(passwd)
CURRY usr.login(passwd) || User.login(usr)(passwd)
CURRY IN PRACTICE struct User { func name() -> String
} let collation: UILocalizedIndexedCollation = ... let sorted = collation.sortedArrayFromArray(users, collationStringSelector: "name")
CURRY IN PRACTICE class Wrapper<T>: NSObject { let payload: T
let localization: (T) -> () -> String @objc func localizable() -> NSString { return localization(payload)() } static var selector: Selector { return "localizable" } }
CURRY IN PRACTICE let wrappers = users.map { Wrapper(payload: $0,
localization: User.name) } let sorted = collation.sortedArrayFromArray(wrappers, collationStringSelector: Wrapper<User>.selector)
FUNCTIONAL ABSTRACTION
OPTIONAL enum Optional<T> { case None case Some(T) }
OPTIONAL func map<U>(f: T -> U) -> U? func flatMap<U>(f:
T -> U?) -> U? let date: NSDate? = ... let formatter: NSDateFormatter = ... let dateString = date.map(formatter.stringFromDate)
ARRAY func map<T>(t: Self.Generator.Element -> T) -> [T] func flatMap<S:
SequenceType> (t: Self.Generator.Element -> S) -> [S.Generator.Element]
MONAD<?>
MONAD<ASYNC>
PROMISE class Promise<T> { func then<U>(body: T -> U) ->
Promise<U> func then<U>(body: T -> Promise<U>) -> Promise<U> }
PROMISE class Promise<T> { func map<U>(body: T -> U) ->
Promise<U> func flatMap<U>(body: T -> Promise<U>) -> Promise<U> }
OBSERVABLE class Observable<T> { func map<U>(body: T -> U) ->
Observable<U> func flatMap<U>(body: T -> Observable<U>) -> Observable<U> }
MONAD IN PRACTICE
ASYNC CALLBACK (value: T?, error: ErrorType?) -> Void
ASYNC CALLBACK (value: T?, error: ErrorType?) -> Void if let
error = error { // handle error } else if let value = value { // handle value } else { // all nil? } // all non-nil?!
RESULT enum Result<Value> { case Failure(ErrorType) case Success(Value) }
RESULT (result: Result<T>) -> Void switch result { case let
.Error(error): // handle error case let .Success(value): // handle value }
RESULT enum Result<Value> { func map<T>(...) -> Result<T> { ...
} func flatMap<T>(...) -> Result<T> { ... } }
RESULT func flatMap<T>(@noescape transform: Value throws -> Result<T>) rethrows ->
Result<T> { switch self { case let .Failure(error): return .Failure(error) case let .Success(value): return try transform(value) } } func map<T>(@noescape transform: Value throws -> T) rethrows -> Result<T> { return try flatMap { .Success(try transform($0)) } }
RESULT func toImage(data: NSData) -> Result<UIImage> func addAlpha(image: UIImage) ->
Result<UIImage> func roundCorner(image: UIImage) -> Result<UIImage> func applyBlur(image: UIImage) -> Result<UIImage>
RESULT toImage(data) .flatMap(addAlpha) .flatMap(roundCorner) .flatMap(applyBlur)
REFERENCE ▸ Wikipedia ▸ Haskell Wiki ▸ Functional Programming in
Swift ▸ objc.io
THANKS Q & A