Slide 1

Slide 1 text

MP in Haskell

Slide 2

Slide 2 text

MP = Monadic Programming 1. モナドとは何か 2. モナドの基本的な扱い方 3. モナド変換子の使い方

Slide 3

Slide 3 text

自己紹介

Slide 4

Slide 4 text

( d e f p r o f i l e 大橋 賢人 [ O H A S H I K e n t ] : c o m p a n y 株式会社オプト テクノロジー 開発2部 : g i t h u b @ l a g e n o r h y n q u e : t w i t t e r @ l a g e n o r h y n q u e : l a n g u a g e s [ P y t h o n H a s k e l l C l o j u r e S c a l a E n g l i s h f r a n ç a i s D e u t s c h р у с с к и й ] : i n t e r e s t s [ プログラミング 語学 数学] )

Slide 5

Slide 5 text

モナド(Monad) とは 一言で言えば、 > > = (bind) できる型クラス(type class)。 m a -> (a -> m b) -> m b 型クラスFunctor, Applicative の上位互換。 - - H a s k e l l c l a s s A p p l i c a t i v e m = > M o n a d m w h e r e ( > > = ) : : f o r a l l a b . m a - > ( a - > m b ) - > m b r e t u r n : : a - > m a . . . / / s c a l a z . M o n a d t r a i t M o n a d [ F [ _ ] ] e x t e n d s A p p l i c a t i v e [ F ] w i t h B i n d [ F ] { a b s t r a c t d e f b i n d [ A , B ] ( f a : F [ A ] ) ( f : ( A ) ⇒ F [ B ] ) : F [ B ] a b s t r a c t d e f p o i n t [ A ] ( a : ⇒ A ) : F [ A ] . . . }

Slide 6

Slide 6 text

モナドの具体例 例えば、 。 M a y b e 型クラスFunctor, Applicative, Monad のインスタンスになっている。

Slide 7

Slide 7 text

Functor の f m a p / < $ > (a -> b) -> f a -> f b n : : M a y b e I n t n = J u s t 1 f : : I n t - > S t r i n g f = \ x - > s h o w x - - f m a p f m a p f n - - < $ > f < $ > n - - > > = による実装 n > > = r e t u r n . f - - d o 記法による実装 d o a < - n r e t u r n $ f a

Slide 8

Slide 8 text

Applicative の < * > f (a -> b) -> f a -> f b n : : M a y b e I n t n = J u s t 1 f : : M a y b e ( I n t - > S t r i n g ) f = J u s t $ \ x - > s h o w x - - < * > f < * > n - - > > = による実装 n > > = \ a - > f > > = \ g - > r e t u r n $ g a - - d o 記法による実装 d o a < - n g < - f r e t u r n $ g a

Slide 9

Slide 9 text

Monad の > > = m a -> (a -> m b) -> m b n : : M a y b e I n t n = J u s t 1 f : : I n t - > M a y b e S t r i n g f = \ x - > J u s t $ s h o w x - - > > = n > > = f - - d o 記法による実装 d o a < - n f a

Slide 10

Slide 10 text

同種のモナドを扱う場合 例えば、 M a y b e を単独で使う場合

Slide 11

Slide 11 text

同種のモナドを扱う場合 (1) パター ンマッチ 構造に注目して分解(unapply, destructure) する。 d a t a U s e r = U s e r { f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r N a m e : : U s e r - > M a y b e S t r i n g u s e r N a m e U s e r { f i r s t N a m e = J u s t f , l a s t n a m e = J u s t l } = J u s t $ f + + " " + + l u s e r N a m e _ = N o t h i n g

Slide 12

Slide 12 text

同種のモナドを扱う場合 (2) 高階関数 高階関数 > > = , etc. を組み合わせる。 d a t a U s e r = U s e r { f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r N a m e : : U s e r - > M a y b e S t r i n g u s e r N a m e u s e r = f i r s t N a m e u s e r > > = \ f - > l a s t N a m e u s e r > > = \ l - > r e t u r n $ f + + " " + + l

Slide 13

Slide 13 text

同種のモナドを扱う場合 (3) d o 記法 モナドのためのシンタックスシュガー を活用する。 d a t a U s e r = U s e r { f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r N a m e : : U s e r - > M a y b e S t r i n g u s e r N a m e u s e r = d o f < - f i r s t N a m e u s e r l < - l a s t N a m e u s e r r e t u r n $ f + + " " + + l

Slide 14

Slide 14 text

異種のモナドが混在する場合 例えば、 M a y b e と を組み合わせて E i t h e r E i t h e r e ( M a y b e a ) として扱う必要がある場合

Slide 15

Slide 15 text

異種のモナドが混在する場合 (1) パター ンマッチ d a t a U s e r = U s e r { i d ' : : I n t , f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r R o l e : : I n t - > E i t h e r E r r o r R o l e u s e r R o l e i = u n d e f i n e d u s e r I n f o : : U s e r - > E i t h e r E r r o r ( M a y b e S t r i n g ) u s e r I n f o u s e r = c a s e u s e r R o l e $ i d ' u s e r o f R i g h t r - > c a s e u s e r o f U s e r { f i r s t N a m e = J u s t f , l a s t N a m e = J u s t l } - > R i g h t . J u s t $ f + + " " + + l + + " : " + + s h o w r _ - > R i g h t N o t h i n g L e f t e - > L e f t e

Slide 16

Slide 16 text

問題点 複数階層のモナドの分解・ 再構築が煩わしい 構造に強く依存しているため変更に弱い パター ンマッチがネストして書きづらく読みづらい

Slide 17

Slide 17 text

異種のモナドが混在する場合 (2) 高階関数 d a t a U s e r = U s e r { i d ' : : I n t , f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r R o l e : : I n t - > E i t h e r E r r o r R o l e u s e r R o l e i = u n d e f i n e d u s e r I n f o : : U s e r - > E i t h e r E r r o r ( M a y b e S t r i n g ) u s e r I n f o u s e r = u s e r R o l e ( i d ' u s e r ) > > = \ r - > r e t u r n $ f i r s t N a m e u s e r > > = \ f - > l a s t N a m e u s e r > > = \ l - > r e t u r n $ f + + " " + + l + + " : " + + s h o w r

Slide 18

Slide 18 text

問題点 構造を直接扱う必要はないが関数がネストして書きづらく読みづらい

Slide 19

Slide 19 text

異種のモナドが混在する場合 (3) d o 記法 d a t a U s e r = U s e r { i d ' : : I n t , f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r R o l e : : I n t - > E i t h e r E r r o r R o l e u s e r R o l e i = u n d e f i n e d u s e r I n f o : : U s e r - > E i t h e r E r r o r ( M a y b e S t r i n g ) u s e r I n f o u s e r = d o r < - u s e r R o l e $ i d ' u s e r r e t u r n $ d o f < - f i r s t N a m e u s e r l < - l a s t N a m e u s e r r e t u r n $ f + + " " + + l + + " : " + + s h o w r

Slide 20

Slide 20 text

問題点 関数はネストしないがd o 記法が連鎖して書きづらく読みづらい

Slide 21

Slide 21 text

モナド変換子(monad transformer) とは 一言で言えば、 あるモナドに別のモナドを上乗せ( 合成) したモナド。 ネストしたモナドをネストしていないかのように扱えるようになる。 e.g. , , M a y b e TE i t h e r TL i s t T

Slide 22

Slide 22 text

モナド変換子の生成と変換 - - M ( モナド) とM a y b e でネストしたモナド m M a y b e A : : M ( M a y b e a ) - - M a y b e とM を合成したM a y b e T m a y b e T M A : : M a y b e T M a - - M a y b e m a y b e A : : M a y b e a - - M m A : : M a - - M ( M a y b e a ) → M a y b e T M a M a y b e T m M a y b e A - - M a y b e T M a → M ( M a y b e a ) r u n M a y b e T m a y b e T M A - - M a y b e a → M ( M a y b e a ) → M a y b e T M a M a y b e T $ r e t u r n m a y b e A - - M a → M a y b e T M a l i f t m A

Slide 23

Slide 23 text

モナド変換子の導入 ここではモナド変換子 M a y b e T を利用して M a y b e と E i t h e r を合成してみる。

Slide 24

Slide 24 text

i m p o r t C o n t r o l . M o n a d . T r a n s . C l a s s i m p o r t C o n t r o l . M o n a d . T r a n s . M a y b e d a t a U s e r = U s e r { i d ' : : I n t , f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r R o l e : : I n t - > E i t h e r E r r o r R o l e u s e r R o l e i = u n d e f i n e d u s e r I n f o : : U s e r - > E i t h e r E r r o r ( M a y b e S t r i n g ) u s e r I n f o u s e r = r u n M a y b e T $ d o r < - l i f t . u s e r R o l e $ i d ' u s e r f < - M a y b e T . r e t u r n $ f i r s t N a m e u s e r l < - M a y b e T . r e t u r n $ l a s t N a m e u s e r r e t u r n $ f + + " " + + l + + " : " + + s h o w r

Slide 25

Slide 25 text

M a y b e a と E i t h e r e a をd o 記法1 つでシンプルに扱える モナド変換子への変換がやや冗長

Slide 26

Slide 26 text

さらにリファクタ モナド変換子への変換を関数として抽出してみる。

Slide 27

Slide 27 text

i m p o r t C o n t r o l . M o n a d . T r a n s . C l a s s i m p o r t C o n t r o l . M o n a d . T r a n s . M a y b e d a t a U s e r = U s e r { i d ' : : I n t , f i r s t N a m e : : M a y b e S t r i n g , l a s t N a m e : : M a y b e S t r i n g } d e r i v i n g S h o w u s e r R o l e : : I n t - > E i t h e r E r r o r R o l e u s e r R o l e i = u n d e f i n e d f r o m M a y b e : : M a y b e a - > M a y b e T ( E i t h e r E r r o r ) a f r o m M a y b e = M a y b e T . r e t u r n u s e r I n f o : : U s e r - > E i t h e r E r r o r ( M a y b e S t r i n g ) u s e r I n f o u s e r = r u n M a y b e T $ d o r < - l i f t . u s e r R o l e $ i d ' u s e r f < - f r o m M a y b e $ f i r s t N a m e u s e r l < - f r o m M a y b e $ l a s t N a m e u s e r r e t u r n $ f + + " " + + l + + " : " + + s h o w r

Slide 28

Slide 28 text

Further Reading Functor, Applicative, Monad のシンプルな定式化 - Qiita Scala でFuture とEither を組み合わせたときに綺麗に書く方法 - scala とか・・・ Scalaz Monad Transformers - Underscore 独習 Scalaz — モナド変換子 Easy Monad Haskell モナド変換子 超入門 - Qiita All About Monads - Sampou.Org Source Code Gist - lagenorhynque - monad-transformers