Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MP in Haskell

MP in Haskell

「MP in Scala」のスピンオフ(Haskell版)。
cf. Scala版: https://speakerdeck.com/lagenorhynque/mp-in-scala

Haskellでもモナディックプログラミング!

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

Kent OHASHI

May 28, 2016
Tweet

More Decks by Kent OHASHI

Other Decks in Programming

Transcript

  1. ( 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 [ プログラミング 語学 数学] )
  2. モナド(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 ] . . . }
  3. 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
  4. 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
  5. 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
  6. 同種のモナドを扱う場合 (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
  7. 同種のモナドを扱う場合 (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
  8. 同種のモナドを扱う場合 (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
  9. 異種のモナドが混在する場合 例えば、 M a y b e と を組み合わせて E

    i t h e r E i t h e r e ( M a y b e a ) として扱う必要がある場合
  10. 異種のモナドが混在する場合 (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
  11. 異種のモナドが混在する場合 (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
  12. 異種のモナドが混在する場合 (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
  13. モナド変換子の生成と変換 - - 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
  14. 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
  15. M a y b e a と E i t

    h e r e a をd o 記法1 つでシンプルに扱える モナド変換子への変換がやや冗長
  16. 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
  17. 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