Submit Search
Swiftで説明する「モナド」:Swiftにおける関数型プログラミングの使い方
•
Download as PPTX, PDF
•
16 likes
•
5,923 views
Roy Kim
Follow
FPやHaskellのモナドをSwiftを使って説明してみたけど、過去のものなので今はあまり参考にならないかも。それと内容的にも少し修正が必要。
Read less
Read more
1 of 71
Download now
Downloaded 23 times
More Related Content
Swiftで説明する「モナド」:Swiftにおける関数型プログラミングの使い方
1.
OOP(Swift)で説明するMonad Roy Kim (金
成哲) NCデザイン&コンサルティング株式会社 Swiftで、Functional Prgrammingをどう適用するか?
2.
入る前に 2Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved.
3.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Who am I? 金 成哲 (Roy S. Kim) • @royskimJP •
[email protected]
• UXデザイナー、ITコンサルタント、exエンジニア Work @ NCデザイン&コンサルティング株式会社 • 2011年3月に創業 • 東京4人、関西3人の体制 • 在宅勤務 & コーワーキングスペース • 企業向けのアプリ開発・UXデザイン • サービスデザイン → UX/UIデザイン → 実装 → 運用・改善までを支援 3
4.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Swift 4 >100
5.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Haskell 5 >30
6.
入りながら なぜ、モナド?なぜ、FP? 6Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved.
7.
入りながら なぜ、モナド?なぜ、FP? 7Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 関数型プログラミング (Functional Programming) の略
8.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. モナド(Monad)とは? Wikipediaの説明 • 圏論(けんろん)に基づいた概念 数学の一分野である圏論において、モナド(英語: monad)あるいはトリプル (英語: triple)とは(自己)関手と2つの自然変換の三つ組である。モナドは随伴 関手の理論で使われ、半順序集合上の閉包作用素を任意の圏の上へ一般化する。モ ナドという名前は、対応する圏を一般化するというモナドの動作に注目して、ソー ンダース・マックレーンが哲学用語である「モナド」を借用した。 • 関数型プログラミングにおいての説明 モナド(monad)は計算を表現する構造であり、計算ステップの列からなる。つま り、型がモナド構造をもつというのは、命令を繋げるやり方、言い換えるとその型 をもつ関数をネストさせる規則が定まっていることをいう。これはプログラマがパ イプラインを作ることを可能にする。パイプラインでは入力データを1ステップず つ処理するが、モナドは各アクションに追加の処理規則を上乗せすることができる 8
9.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. モナド(Monad)とは? Wikipediaの説明 • 圏論(けんろん)に基づいた概念 数学の一分野である圏論において、モナド(英語: monad)あるいはトリプル (英語: triple)とは(自己)関手と2つの自然変換の三つ組である。モナドは随伴 関手の理論で使われ、半順序集合上の閉包作用素を任意の圏の上へ一般化する。モ ナドという名前は、対応する圏を一般化するというモナドの動作に注目して、ソー ンダース・マックレーンが哲学用語である「モナド」を借用した。 • 関数型プログラミングにおいての説明 モナド(monad)は計算を表現する構造であり、計算ステップの列からなる。つま り、型がモナド構造をもつというのは、命令を繋げるやり方、言い換えるとその型 をもつ関数をネストさせる規則が定まっていることをいう。これはプログラマがパ イプラインを作ることを可能にする。パイプラインでは入力データを1ステップず つ処理するが、モナドは各アクションに追加の処理規則を上乗せすることができる 9
10.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. モナドはブリトー? 10
11.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Swiftは、マルチパラダイムランゲージ Object Oriented Programming (= OOP) • Cocoa TouchはOOPのフレームワークなので、OOPの採用は必須 Protocol Oriented Programming (= POP) • アップルがWWDC2015で披露、これからのSwiftのパラダイムとして強く展開している • オブジェクトの継承よりProtocolの採用によってより柔軟なコードになる(と言ってい る) • これからの正しい設計は; 親クラスを作って継承(X) プロトコルを作ってそれに準拠した実装(◎) Value Oriented Programming (= VOP) • Swiftのデータタイプは基本Immutable • ImmutableなValue Typeを使うことでより安全なコードになる(と、アップルが WWDC2015にて言っている) • Classes=more complexity. Values=less complexity 11
12.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Swiftは関数型プログラミング言語でもあるのか? Swiftが出たら「関数型プログラミングができる!」とみん な騒いでいるらしい!? • 専門の書籍も出ている(下図を参照) • 「SwiftでFunctional Programming」という題の講演とブログが流行る • FPの手法を採用したサードパーティライブラリーがたくさん出ている 12
13.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 話を進める前に、関数型プログラミングとは? 関数型プログラミングはコーディングスタイル(パラダイムでは なく、言語の仕様でもない) つまり、SwiftでFPをする・しないは選択可能なオプション Functionが値と同等に使える functionを他のfunctionの引数や戻り値として使うことができる ソフトウェアをモジュールとして分離して考える 小さいモジュール(関数)の組み合わせで複雑なシステムを構築する 従って、モジュールの独立性と組み合わせの利便性が大事 副作用(Side Effect)を避ける 参照透明性:同じ引数で関数を呼ぶといつも同じ結果が返ってくることを 保証する 不変性を保つ:Swiftでいう、「let」はあるけど、「var」はない 13
14.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Swift ≒ Haskell !? Swiftは先述した、関数型プ ログラミング言語としての 要件を満たしている • Function is first class object. POP、VOPは実はFPの特徴 でもある(と、言える) そのせいか、Haskellと Swiftの文法の概念的類似性 が半端ない! 14 Swiftet Haskell Protocol Type class Protocol Extension Instanciation of Type class Value Oriented Programming Referencial Transparancy Optional maybe Pattern Matching Pattern Matching guard guard let let typealias type Etc… Etc… 「Swiftって、Haskellのただのぱっくりじゃ ないか?」と思うくらい!
15.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPとSwiftとの関係 Swiftに登場に喜ぶFPファン達、時代の流れはFPに? • 「新しい、しかもApple向けの開発で使えるFP言語ができた!嬉しい!」 • 海外のSwift関連媒体・イベントにはほぼ必ずFPの話が出るように! • 「やっとFPとマーケットが巡り合った時代になった!」と喜ぶ(MSの) 人も。 15 https://channel9.msdn.com/Shows/Going+Deep/Bria n-Beckman-Dont-fear-the-Monads Brian Beckman: Don't fear the Monad Monadを楽しそうに説明してくれる。彼は簡単 だと言っているけど、多分、それはかなり主観 的な話。しかし、結構いい参考にはなる。
16.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 手続き型プログラミング・OOP ハードウェアを意識した世界 操作手順(レジスターやメモーリの操作など)を記述することで問題を解決 関数型プログラミング きれいな数学の世界。 解決方法の記述(関数の繋がり)で問題を解決 プログラミングにおける二つのアプローチ 16 10101000110110110110101101101101110111011010001011 10110111011011010100011011011011010110110110111011 10110100010111011011101101 101010001101101101101011011011011101110110 ボトム アップ トップ ダウン プログラム
17.
図とサンプルコードで見るFPの考え方 17Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved.
18.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPの概念図 18 Int String Function (+) Value(値) 全ては値(Value) つまり、関数も値 • Objective-Cでは値として使える関数はBlockのみ • Swifitは全てが関数であり、Closureは無名関数 List [ ] Function (*) Function (%) Custom Data Type Bool
19.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. サンプル:値としての関数の使用例 19
20.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPの概念図 20 Int (1) Function (+) Value(値) 同じ引数を与えると必ず同じ結果が得られる • 「足し算」という関数に1と2を引数に渡すと必ず3が返ってくる。 • これが「参照透過性がある」ということ。(Referencial Transparancy) Int (2) Int (3) いつやっても、何度 やっても同じ返り値
21.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPの概念図 21 Int (1) Function (+) Value(値) 全ては厳格な型システムによって管理される • 例えば、「足し算」は数字型を二つ引数にもらって、計算結果をまた数 字型で返す型を持つ関数 Int (2) Int (3) Int型の足し算を行う関数の型は (Int, Int) -> Int
22.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPの概念図 22 Int (1) Function (+) Value(値) 部分適用した関数が作れる • 複数の引数が必要な関数に一部の引数だけを与えると、その引数をデ フォルト値として持つ新しい関数ができる • これは、Swiftでもできるよね? Function (+1) 一つだけの引数を必要とする、新しい値(関数)の出来上がり! これは関数の部分適用による関数のカリー化と言う。 この関数の型は、(Int) -> Int
23.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. FPの概念図 23 Int (2) Function (*) Value(値) 関数をつなぐことでより複雑な処理ができる • これはOOPのMethod Chainingに似ている Function (+1) Int (3) Int (7) Intの6が次の関数 の引数となる。 引数6と関数が持って いる値1を足してその 結果を返す
24.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. サンプル:関数の部分適用と連鎖 24
25.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Functional Programming FPの概念図 25 Input Function Value(値) FPはこれらの関数をつなぐことで必要なプログラムを実装 する • 数学的な関数の記述 • どう処理するかではなく、何であるかの記述 Output Function Function
26.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Real World Functional Programming FPの概念図 26 Input Function Value(値) しかし、我らの世界はピュアではない! • ピュアな心だけでは生きていけない! • 不純なことにどう対応するか? Output 副作用(Side Effect)の ない、純粋な世界 Function Function 多様に変化する不純な (?)世界
27.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Real World Functional Programming FPの概念図 27 Input Function Value(値) 汚れ仕事は他人に任せる! • IOアクションという、外部とのやり取りを代行する関数を使う • IOアクションはできるだけ小さく抑える == 不純なものは最小限に! Output 副作用(Side Effect)の ない、純粋な世界 Function Function 多様に変化する不純な (?)世界 IO アクション IO アクション 二つの世界の接点であり、 関門でもあるIOアクション
28.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. アプリ FPを採用したアプリ設計のあるべき姿? 28 iOS SDK Core OS Core Service Media Cocoa Touch Inherited Object ValueFunction Real World Functional Programming Input Function Output Function Function IO アクション IO アクション ValueFunction Conversion Object & ValueObject Object Function Function
29.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. アプリ FPを採用したアプリ設計のあるべき姿? 29 iOS SDK Core OS Core Service Media Cocoa Touch Inherited Object ValueFunction Real World Functional Programming Input Function Output Function Function IO アクション IO アクション ValueFunction Conversion Object & ValueObject Object Function Function 仲介レイヤー • Cocoa Touch、3rd Partyライブラ リーとの連携 • 外部との連携(ネットワーク処理、 ファイルI/O、ユーザー入力の処理な ど) • このレイヤーをできるだけ薄くする のがいい設計(とされている) FP World • 値と関数の型の定義 • 関数の実装 • アプリの機能はここで実装 OOP World
30.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. アプリ しかし課題は残る! 30 iOS SDK Core OS Core Service Media Cocoa Touch Inherited Object ValueFunction ValueFunction Conversion Object & ValueObject Object Function Function 事実上、関数型プログラミングで純粋に 実装するにはCocoa Touchの存在感が大 きすぎる 値をValueとして取り扱うのは難しい • CoreDataも、Realmも、データの表現には Objectを使っている • それらを、FPをするために、都度Value Type に変換するか?(冗談はやめて〜) ベストプラクティスはまだ定まってない • FPとOOPの二つの世界の境界をどこに置くか、 またその仲介をどうするかの考慮が必要
31.
やっと本題 なぜMonad? 31Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved.
32.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ここで復習 32 Value(値) FPは関数をつなげることでやりたいことを実現する • 関数を繋げる == メソッドチェーン Int (2) Function (*) Function (+1) Int (3) Int (7) Intの6が次の関数 の引数となる。 引数6と関数が持って いる値1を足してその 結果を返す 6
33.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 関数の再利用 33 Value(値) FPは関数を定義し、それを組み合わせることで処理を実行 する (+1)という関数(plusOne)をせっかく作ったので、多様な シーンで活用したい! Function (+1) 使いまくるぜ〜!
34.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、このような場合はどうする? • 例えば、引数がOptionalなら?? 関数を再利用する場合の課題 34 Int (2) Function (/) Function (+1) Int (0) Int (7) 計算できないので Nonが次の関数の 引数となる Optional型をどう処理 するか? Int?
35.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Function (+1) しかし、このような場合はどうする? • 例えば、引数がOptionalなら?? 関数を再利用する場合の課題 35 Int (2) Function (/) Int (0) Int (7) 計算できないので Nonが次の関数の 引数となる Optional型をどう処理 するか? Int? If文で対応できる ぜ!
36.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 関数を再利用する場合の課題 36 Value(値) このような場合はどうする? • 例えば、引数が配列なら?? Int (2) Function (tripleValue) Function (+1) Int (7) 配列が次の関数の 引数となる 配列をどう処理す るか? [2,2,2,]
37.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 関数を再利用する場合の課題 37 Value(値) このような場合はどうする? • 例えば、引数が配列なら?? Int (2) Function (tripleValue) Function (+1) Int (7) 配列が次の関数の 引数となる 配列をどう処理す るか? [2,2,2,] forループ文で 対応できるぜ!
38.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、これは関数型プログラミングではない 38 Value(値) やりたいのは関数をつなぐこと 条件分岐やループ文を書いていてはOOPと同じ • (まあ、悪いとは言わないが、FP的ではない!) これらを、 排除したいのだ!
39.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 何が問題なのか? 39 Value(値) 値だけを取り扱うには問題がない しかし、値がOptionalの中にあるか、配列の中に格納されていれ ば、そのままでは使えない • OptionalはIntではない、ArrayもIntではない。つまり、データ型が違う! Int Function (+1) Int Optional IntInt Int Array Int型だけ、 受付るよ〜
40.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ここで文脈、あの有名な「箱」が登場 40 Value(値) このような値が何かの状態をもっていることを「文脈の中にある」と 表現する 文脈はよく「箱」と比喩される • 多様な文脈が存在するし、自作することもできる Int Int Optional IntInt Int Array • 値のみ • 文脈がないのでこのまま使える • 値が文脈の中にある。 • Optionalは「値があるかもないかもしれない」 という意味の文脈 • 値が文脈の中にある。 • 配列は「値がいくつあるかしれない」という意 味の文脈
41.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. じゃあ、どうするか? 41 Value(値) なら、文脈の中から値だけ抜き出せばいい! すると、関数が適用できるよ〜 Int Function (+1) Int Optional IntInt Int Array Int Int Int Int
42.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. じゃあ、どうするか? 42 Value(値) OOPでif分やforループでやってたのがまさにこれ! • つまり、値がどの文脈に入っているかによって、取り出す方法が異なる Int Function (+1) Int Optional IntInt Int Array Int Int Int Int Ifでやってた! Forループで やってた!
43.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. もっと行儀よくしようぜ! 43 Value(値) 値を文脈の中から取り出して、関数の適用が終わったら、また元 の文脈の中に入れてあげる! • サービス精神旺盛! Function (+1) Int Optional IntInt Int Array Int IntInt Int Int Optional IntInt Int Array Int Int Int Int
44.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ちょっと待って、この処理は汎用化できないか? 44 Value(値) 文脈は異なっても、やっていることは同じ • 文脈から値を取り出す ⇒ 関数を適用する ⇒ 元の文脈の中に値を返す Function (+1) Int Optional IntInt Int Array Int IntInt Int Int Optional IntInt Int Array Int Int Int Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す
45.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ちょっと待って、この処理は汎用化できないか? 45 Value(値) 文脈は異なっても、やっていることは同じ • 文脈から値を取り出す ⇒ 関数を適用する ⇒ 元の文脈の中に値を返す Function (+1) Int Optional IntInt Int Array Int IntInt Int Int Optional IntInt Int Array Int Int Int Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す
46.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ちょっと待って、この処理は汎用化できないか? 46 Value(値) パターンが見えてきた!Protocolとして定義して、文脈ご とに拡張する? Function (+1) Int Optional IntInt Int Array Int IntIntInt Int Optional IntInt Int Array Int IntInt Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す コード引用: https://gist.github.com/mbrandonw/42651182eddf53ca3991
47.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ちょっと待って、この処理は汎用化できないか? 47 Value(値) パターンが見えてきた!Protocolとして定義して、文脈ご とに拡張する? Function (+1) Int Optional IntInt Int Array Int IntIntInt Int Optional IntInt Int Array Int IntInt Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す コード引用: https://gist.github.com/mbrandonw/42651182eddf53ca3991
48.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. ちょっと待って、この処理は汎用化できないか? 48 Value(値) パターンが見えてきた!Protocolとして定義して、文脈ご とに拡張する? Function (+1) Int Optional IntInt Int Array Int IntIntInt Int Optional IntInt Int Array Int IntInt Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す Functor • このように、中の値に対して関数を適用する手段(fmap 関数)を提供する文脈を表すデータ型をHaskellでは Functorと言う • Swiftではmap関数として提供される。 • つまり、map関数を持っているデータ型はFunctorと言え る
49.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. これは、発想の逆転? 49 Value(値) Functor型の導入によって文脈のことは気にせずに関数の再利用 ができる • FunctorはOOPにはない、文脈のデータ型 • fmap関数は文脈の制御を一般化した関数 Function (+1) Int Optional IntInt Int Array Int IntIntInt Int Optional IntInt Int Array Int IntInt Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す Function (+1) Functor fmap()
50.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. これは、発想の逆転? 50 Value(値) Functor型の導入によって文脈のことは気にせずに関数の再利用 ができる • FunctorはOOPにはない、文脈のデータ型 • fmap関数は文脈の制御を一般化した関数 Function (+1) Int Optional IntInt Int Array Int IntIntInt Int Optional IntInt Int Array Int IntInt Int Function (+1) 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す Function (+1) Functor fmap()
51.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Functor導入の価値 51 Value(値) Functor型の導入によって、 • if/forなどの制御文の記述が不要になる • コードが簡潔になる
52.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Functor導入の価値 52 Value(値) Functor型の導入によって、 • if/forなどの制御文の記述が不要になる • コードが簡潔になる • 関数の繋ぎが楽にできる
53.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、この場合はどうするか? 箱(文脈)の中の値に対して適用する関数がさらに文脈のある値 を返すならどうなるか? • 例えば、Intを引数にもらって、Arrayを返す関数を連続して繋げば? 53 Int (3) Function (tripleValue) Function (tripleValue) 配列の[3,3,3]が次 の関数の引数とな る ?
54.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、この場合はどうするか? 箱(文脈)の中の値に対して適用する関数がさらに文脈のある値 を返すならどうなるか? • 例えば、Intを引数にもらって、Arrayを返す関数を連続して繋げば? 54 1回目は普通に成功 2回目も成功するが、返り値は 2重配列になっている! 3回目はさすがに失敗!! 引数の型が違うと怒られる!
55.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、この場合はどうするか? 箱(文脈)の中の値に対して適用する関数がさらに文脈のある値 を返すならどうなるか? • 例えば、Intを引数にもらって、Arrayを返す関数を連続して繋げば? 55 Int (3) Function (tripleValue) Function (tripleValue) Int Int Int Array Array 今、この状態!
56.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. しかし、この場合はどうするか? 箱(文脈)の中の値に対して適用する関数がさらに文脈のある値 を返すならどうなるか? • 例えば、Intを引数にもらって、Arrayを返す関数を連続して繋げば? 56 Int (3) Function (tripleValue) Function (tripleValue) Int Int Int Array この状態になれば OK! Int Int Int Int Int Int Int Int Int Array
57.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. これは他の文脈でも同じことが言える! 先ほどの、Optionalを返す関数を連続してつなげると、 Optionalの中にOptionalが入ってしまう。 57 Function (/) Int OptionalInt (20) Function (/) Int (2) Int Optional Optional これじゃあ、 繋げない!
58.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. これは他の文脈でも同じことが言える! 先ほどの、Optionalを返す関数を連続してつなげると、 Optionalの中にOptionalが入ってしまう。 58 Function (/) Int OptionalInt (20) Function (/) Int (2) Int Optional この状態になれば OK!
59.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Monad Funtor もう一つのパターンが見えてきた! fmapを使って関数を適用するけど、その関数の返り値が文脈を 持っている場合は、それを外して返す • 余計な文脈の重複を避ける処理を追加したパターン ⇒ これがモナド! 59 Function (/) Int 文脈 Int Int 文脈 文脈から値を取り出す 値に関数を適用 値を元の文脈の中に返す 文脈 Int 文脈 文脈 Int 文脈 Functor + α == Functorの強化版
60.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. MonadのProtocol定義 60 Value(値) Haskellの定義を参考にSwiftのProtocolとして定義したら以下の ような感じ • MonadがFunctorの拡張であることがわかる コード引用: https://gist.github.com/mbrandonw/42651182eddf53ca3991
61.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. MonadのProtocol定義 61 Value(値) Haskellの定義を参考にSwiftのProtocolとして定義したら以下の ような感じ • MonadがFunctorの拡張であることがわかる Monad • 文脈を意識せず、連続した関数の適用が可能な文脈を表 すデータ型 • SwiftではflatMap関数として提供される。 • つまり、flatMap関数を持っているデータ型はMonadと言 える コード引用: https://gist.github.com/mbrandonw/42651182eddf53ca3991
62.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. flatMapを使った場合のコード 62 1回目は普通に成功 2回目も成功するが、返り値は 2十配列になっている! 文脈が深くならず、関数を連 鎖させることができる
63.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. flatMapを使った場合のコード 63 1回目は普通に成功 2回目も成功するが、返り値は 2十配列になっている! flapMapを使っているなら、 あなたはMonadを 使っているんですよ〜!
64.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. で、Monadは何か?それは必要か? Functor、(Applicative Functor、)Monadは • FPで関数を文脈を意識せずに繋げるためのデザインパターン • OOPではifやforループを用いて、プログラムの処理の一部として記述するものを、データ型ご とに事前に実装したもの • すごく簡単に言うと、 Functorはmapを使って関数を渡せば、都合よく実行してくれるデータ型の総称 MonadはflatMapを使って関数を渡せば、都合よく実行してくれるデータ型の総称 • 使うのは簡単、作るには本文書の内容の他に、「Functor則」、「Monad則」というルールを 守る必要がある しかし、SwiftにMonad(able?)というProtocolはない • 「SwiftはFPじゃないよ。FPの特徴を持っているだけ!」という声も。 どこまで純粋な関数型プログラミングにしたいか? • そこに何の意味があるか? 64
65.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. モナドはブリトー? 65 判断はお任せ! (観点による)
66.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. Why Monad? == Why FP? Immutableでより安全なコードが書ける • コンパイル時の最適化によるパフォーマンス向上 関数を作成し、それらを繋げるだけでコードが書ける • 複雑なものを複数の小さい関数に分けて対応できる Functor、 (Applicative Functor、) Monadなどの概念を理解し、 コードに適用することでより簡潔なコードが書ける • これらの概念を理解できなくても、map、flatMap、reduceなど、FPから由来するメ ソッドを適切に使うとコードをより簡潔に記述できる 参照透過性によって単体テストのためのコードがより簡単になる • ただし、コードを適切に書いた場合のみ! 66
67.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 実際には、SwiftでのFP適用には課題がある! Swiftが依存するCocoa/CocoaTouchはOOPベースのフレーム ワーク • OOPを完全に排除し、純粋な関数型プログラミングを行うのは不可能 • SwiftにFPを採用するには、OOPとの共存の方法を考える必要がある FPは難しい • FPの経験者・有識者が圧倒的に少ないのが現状 • 実際どうかは置いといて、FPは難しいという印象が広がっている • FPに基づいた適切な設計には脳内改革が必要。しかし、今までのOOPの知識 と経験がそれを邪魔する • あなたが頑張って書いたコードはFPを知らない同僚の開発者には理解できな い⇒メンテできないコードの誕生 67
68.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 現段階の結論:FP @ Swift? アップルはFunctionalの「F」も言っていない。 • つまり、ただ開発者達が勝手に思い込みで先走っている可能性もある • しかし、時代がFPの流行を迎えているのは事実 個人的な姿勢 • FPで色々なチャレンジを行い、学習する。時代に遅れをとらないように頑張る 開発チームの一員としての姿勢 • 個人が勝手にFPの手法を乱用しない • コーディング規約と設計のガイドラインを提示して品質を均一化する • チームメンバーの学習の機会を設け、徐々にスフトする仕組みを作る 結論:前向きな様子見 68
69.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. 開発チームとFPとの付き合い方(案) iOS、Swiftを意識した、現段階での現実的な対応は恐らく下記の 通り • 一部のプラクティスは先行的に導入 Value Typeの活用 できるだけ副作用のない設計を心がける map、flatMapなどのメソッドを列挙型の単純なメソッドとしての活用 Functor、Applicative、Monadoなど、FPの概念、記法を理解する必要があるものの活 用はまだ考慮しない • 今後の準備 開発メンバーの教育をしながらFPの活用事例やプラクティスがより広がることを待つ 先ずは社内の小規模のプロジェクトから始め、徐々に広げる フレームワークの作成など、多数のアプリから共有されるようなものを作成する際には 内部設計として採用を考慮する 69
70.
Copyright ©2014, NC
Design & Consulting Co., Ltd. All rights reserved. リソース 70 他に、Githubにて、SwiftとMonadで検索!
Download