2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

17
「やらなければならないこと」としてのHaskellの Monad 山本悠滋 2014-05-11

Upload: -

Post on 22-May-2015

819 views

Category:

Software


0 download

DESCRIPTION

なんとなく分かりづらいと思っていたHaskellのモナドについて、 「型クラスとしてのMonad」や、実際のMonadの使われ方に基づいて、 プログラマ視点で説明してみました。 まとめ - HaskellのMonadは型クラス - 型クラスは、同じ振る舞いをする型達を、まとめて扱うために使用する。 - Monadは「値を返すたびにやらなければならないこと」をまとめる。

TRANSCRIPT

Page 1: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

「やらなければならないこと」としてのHaskellのMonad

山本悠滋

2014-05-11

Page 2: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

はじめまして!山本悠滋(@igrep) 25歳♂

Sansanという会社でRailsを触ってます。

Haskellの勉強会をツキイチでやってます!

Page 3: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

今日話すこと・話さないことやたら難しいと言われるHaskellのMonadについて私なりの理解を説明してみます。

これ↓

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b -- 以下略

圏論のモナドはよくわかりません!

「もう知ってるぜ!」という部分も多いかとは思いますがあしからず。

Page 4: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

先に結論HaskellのMonadを「関数が値を返す度にやらなければならないこと」として捉えると、なんだかいろいろスッキリ理解できたよ!

Page 5: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

Monadは型クラス(再掲)こんな感じのやつ↓

class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b -- 以下略

Page 6: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

そもそも型クラスってまぁ言ってしまえば

JavaやC#などのinterface

Rubyのmix-inされるmodule

みたいなもの

=> 同じ振る舞いをする型達を、ひっくるめて扱う仕組み

Page 7: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

型クラスのいいところ新しい型を作った時、必要なメソッドを定義しておくだけで、その型クラスに対して使える色々な関数が使える!

新しい型に固有な、新しい型のみに必要な処理は、必要な(未定義の)メソッドに全て押し込めちゃえばいい!

Page 8: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

Monadの場合は?必要なreturnメソッドと(>>=)メソッドを定義しておくだけで!

do記法を使ったり、

いろいろできる!

新しいMonad(クラスのインスタンス)に固有な処理は、必要な(未定義の)メソッドに全て押し込めちゃえばいい!

Page 9: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

ここで(>>=)を見てみましょう。(>>=) :: m a -> (a -> m b) -> m b

他の型クラスと同様、Monadも必要なメソッド(>>=)に、固有の処理を書くことで、抽象化している。

Page 10: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

ここで(>>=)を見てみましょう。(>>=) :: m a -> (a -> m b) -> m b

例えば...Maybeでは、m aのaを(a -> m b)に渡すため、Just aなのかNothingなのかどうか判定している

Readerでは、m aのaを(a -> m b)に渡すため、関数に、足りない分の引数を与えている

Parserでは、m aのaを(a -> m b)に渡すため、与えられた文字列を消費している

Page 11: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

ここで(>>=)を見てみましょう。(>>=) :: m a -> (a -> m b) -> m b

いずれも、m aのaを(a -> m b)に渡すために、必要な処理をそれぞれ持っている。

そして、(a -> m b)が返したm bをまた別の関数に渡すよう、必要な処理を繰り返している。

Page 12: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

つまり!!Monadは(>>=)のm aのaを(a -> m b)に渡す部分に、やらなければならないことをすべて押し込んでいる!

(a -> m b)が値を返す度に、別の(a -> m b)な関数にMonadに包まれていない値を渡すために、やらなければならないことを(>>=)に任せている。

Page 13: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

要するに!!(a -> m b)という型の、値を返す度に、やらなければならないことがある関数がいっぱいある時、Monadは役に立つ。

Page 14: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

例えば!!「失敗したのかどうか、実行する度に確認しなきゃいけない」関数がいっぱいあるときは、=> Maybe Monad

「実行する度に、結果のログを追記しなきゃいけない」関数がいっぱいあるときは、=> Writer Monad

「実行する度に、入出力など、何かしら副作用のある計算をしなきゃいけない」関数がいっぱいあるときは、=> IO Monad

Page 15: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

で、なにがうれしいの?「文脈だ!」とか、

「手続きだ!」とか、

「いやモナドだ!」とか、

いろいろとMonadを簡単に言い換える言葉は多く出てきたけど、どれも結構抽象的で、ピンと来なかった。

Page 16: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

で、なにがうれしいの?それに対して「関数が値を返すたびにやらなければならないこと」だと、

少なくともわれわれプログラマはイメージしやすい(はず)。

あくまでも「型クラスとしてのMonad」の性質に即して説明できる。

「どう役立つか」説明できるので、メリットを感じさせやすい。

特に「毎回やらなければならないことを一箇所にまとめられる」と言えば、 コードのDRYさに敏感な人に効果がありそう。

「失敗系」とか「状態系」とかに分けなくていい。

Page 17: 2014 05-11-関数型lt大会-「やらなければならないこと」としてのhaskellのmonad

まとめHaskellのMonadは型クラス

型クラスは、同じ振る舞いをする型達を、まとめて扱うために使用する。

Monadは「値を返すたびにやらなければならないこと」をまとめる。

こうして、おびただしい数のMonadチュートリアルの歴史に、 また一つ新たなページを刻んでしまうのであった...。