Skip to main content
Applicative Functors
in Swift
@kazu0620
自己紹介
坂本 和大( @kazu0620 )
Sansan株式会社 Eight事業部所属
過去に個人で開発したアプリ
- 秘密のアルバム(40万DL!)
- にゃんこ(15万DL!)
はじめに
Swift その2 Advent Calendar 2015
• 「Optionalな文字列同士を良い感じに結合す
る」という記事を書いた
http://qiita.com/kazu0620/items/f2a6272c6b8b7bcbaa42
• アプリカティブスタイルについてのコメント
を@koher さんから頂いた!
curry(+) <^> a <*> b
RunesとCurryというライブラリを利用すると上記の
様な表現が出来るとのこと!
便利そうだが…
• <*>とは?
• curryって関数は何してるのか?
• <^>って何だろ?
• 具体的に何がどう嬉しいのか?
ので、調べてみた
本日のゴール
が何をしてるのか理解して、Runesでアプリカ
ティブスタイルを使えるようになる!
curry(+) <^> a <*> b
箱の話をしよう
「文脈と値を持った箱」という
ものがあるらしい
• Optionalは箱(よく聞くやつ)
• ArrayもOptionalと同じく箱(たまに聞くや
つ)
• つまり...?
reference: Functors, Applicatives, And Monads In Pictures(最高の資料)
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
• 2(a)という「値」と、計算が失敗したかもしれな
い(nilかもしれない)という「文脈」を持ってい
る。
reference: Functors, Applicatives, And Monads In Pictures
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
• 箱に入った値に対して、関数を適用するには?
• 箱から開けないと(unwrap)、関数を適用できな
い
箱を開けずに関数を適用する
には?
朗報
「箱」たちは、基本的にすべ
て箱を開けずに値を操作する
ための関数を持っている!
map
• mapは、箱を開けることなく値を操作するためのメ
ソッド
• さっきから「箱」と呼んでるものはこのmapという
メソッドを備えている
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
reference: Functors, Applicatives, And Monads In Pictures
Fanctorとは?
Fanctor
• 実はすでにFanctorについては説明済み
• さっきから言ってる「箱」 = Fanctor
• Fanctorは、文脈(nilかもしれない…など)を持った値
• mapを使うと文脈を保ったまま関数を値に適用できる
• 厳密には、Fanctor則と呼ばれるルールを満たす型のこと
• mapを利用して、箱を開けることなく中の値
を操作できる。配列も同じ。
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
reference: Functors, Applicatives, And Monads In Pictures
Applicative Functorとは?
Applicative Functor
• Fanctorのすごいやつ
• Swiftの場合は、言語仕様にはない。が、
Runesというライブラリを利用すれば実現で
きる。
• 何ができるのか…?
<*>
<*>とApplicative Functor
• Fanctorがmapを備えていたように、
Applicative Functorは<*>を備えている
• <*>は「箱に包まれた関数」と「箱に包まれ
た値」を引数にとる
<*>とApplicative Functor
• 「箱に包まれた値」
• 「箱に包まれた関数?」
Optional(箱)の中にはクロージャだって格納できる
<*>とApplicative Functor
を
に、箱を開けずに適用するには?
<*>とApplicative Functor
flatMap+mapでもできなくはないが…
<*>を使った方がシンプル&わかりやすい!
<*>は を に適用している
<*>とApplicative Functor
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
reference: Functors, Applicatives, And Monads In Pictures
Applicative Functorは、箱の中の関数を、箱
の中の値に適用してくれる!
引数が複数ある関数
複数のOptional値に対して関数を適用したい
とき<*>は便利!
sumThreeElementsというOptionalではない値を引数
にとる関数をx, y, z(Optional) に適用できてる!
・そして、さりげなく現れた「curry」
引数が複数ある関数
curryは、Curryというライブラリのメソッ
ド。これを呼び出さないと、
になる。<*>は「箱に包まれた関数」と「箱に
包まれた値」を引数にとる。
「箱に包まれた値」<*>「箱に包まれた値」
引数が複数ある関数
これの返り値が関数であってほしい…
引数:x 

返り値:yを引数とする関数(その返り値はzを引数
とする関数)
にsumTreeElementsを変換することさえ出来れば…
カリー化(高階関数)
• 高階関数: 引数として関数をとったり返り値と
して関数を返す関数
• カリー化: 複数の引数をとる関数を、1つの引
数を取り、残りの引数をとる関数に定義を書
き換えること(多分)
引数が複数ある関数
というわけで、Curryを利用してカリー化す
ることで、複数の引数がある関数も適用でき
るように!
返り値は「箱に包まれた関数」
返り値は「箱に包まれた関数」
pure
• +もカリー化して、<*>で繋げて書くことが出来る
• pureは、.Someと同じ。「文脈を持った箱」のデ
フォルト値で包む。
• じゃ、.Someで良いじゃん?
pure
• xやyがOptional型とは限らない
• アプリカティブスタイルは、アプリカティブ
則を満たす型なら何にでも適応できる
• pureを使っておけば中の値がArrayでも安心
同じ
さらに
• result1とresult2は同じ結果になる
• このa.map(f)の記述は頻出なのでショートカットが用意
されている
• <^> !
<^>
• 上記の3つは、同じ処理
• <^> を使うことで、(+)をxとyに適用するんだ
ぞ、ということがわかりやすくなる
というわけで
curry(+) <^> a <*> b
• +という関数をカリー化し
• Optionalのデフォルト値(.Some)でその関数を包み
• <*>を使い、Optionalに包まれたaとbに、unrwap
することなく+を適用している
※わかりやすさのためにOptionalと書いたが、アプリカティブ則を満たす型ならな
んでも良い
で、結局何が便利なの?
アプリカティブスタイルのメリット
• Optionalでない値を取る関数も、Unwrapせず
にOptionalに適用できる
• 複数のOptionalをUnwrapすることなく計算で
きる
• プロダクトで使ってみて、他良いとこあったら共
有します!
Functor, Applicative, そしてMonadについてもっと知り
たい方は…
We're hiring!
• Sansan株式会社では、Swiftを書くのが好きなエ
ンジニアを絶賛募集中
• Kotlin好きなandoridエンジニアも絶賛募集中
• React.jsをゴリゴリ書きたいフロントエンジニア
も
• ruby/C#なエンジニアも!
We're hiring!
• 興味あれば、 wantedlyか会社の採用ページから
応募を!
• https://www.wantedly.com/companies/
Sansan/projects
• http://jp.corp-sansan.com/recruit/job/
index.html
• (@kazu0620にコッソリ連絡くれる、でもOK)
ご静聴ありがとうございました