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
110
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Functional Programming Practice in Swift
Swift 函数式编程实践
2016年1月10日在 @Swift 大会上的分享
Hank Bao
January 10, 2016
More Decks by Hank Bao
See All by Hank Bao
Notes on Gamification
hankbao
0
130
Reverse Engineering: from Objective-C to Swift
hankbao
2
460
Type-safe Programming Practice in Swift
hankbao
0
120
Other Decks in Programming
See All in Programming
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
170
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
150
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
3
1.5k
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
140
トークンをケチるな、設計しろ:GitHub Copilotを賢く使うコンテキスト戦略
ochtum
0
320
なぜ関数型プログラミングで「型」と「証明」が語られるのか #fp_matsuri
kajitack
3
960
琵琶湖の水は止められてもNet--HTTPのリトライは止められない / You might be able to stop the water flow of Lake Biwa but you can't stop Net::HTTP retries
luccafort
PRO
0
400
SLOをサービス品質の共通言語にするために 取り組んできたこと
wakana0222
0
510
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
250
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
530
どこまでゆるくて許されるのか
tk3fftk
0
500
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
460
Featured
See All Featured
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
540
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
How to train your dragon (web standard)
notwaldorf
97
6.7k
sira's awesome portfolio website redesign presentation
elsirapls
0
300
Side Projects
sachag
455
43k
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
180
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
64
56k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
Optimising Largest Contentful Paint
csswizardry
37
3.8k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.6k
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