TL;DR
内容
モナディック関数
モナディック関数は、「通常」の値を受け取り、ある種の「拡張」された値を返す関数である。Domain Modeling Made Functional 第10章 Result を生成する関数の連鎖(bind と errorMap、map)に当てはめると、「拡張」された値は Result 型で包まれた値である。したがって、モナディック関数はスイッチ関数のことである。
モナド
モナドは、モナディック関数を直列につなげられるものである。アプリカティブをさらに抽象化した概念で、コンテキスト(コンテナ)の中の値に基づいて新しいコンテキストを作る。技術的には、次の 3 つの要素を持つ。
1 つめはデータ構造で、たとえば Result である。2 つめは関連する関数である。return(pure)は「通常」の値を「拡張」された値に変換する関数で、Result では Ok コンストラクタがこれに当たる。bind(flatMap)はモナディック関数を連鎖させる関数で、Result では次のように書ける。
let bind f aResult =
match aResult with
| Ok success -> f success
| Error failure -> Error failure3 つめは、関数がどう動作しなければならないかを定めるルールで、Haskell ではモナド則と呼ばれる。
return x >>= f = f x
mx >>= return = mx
(mx >>= f) >>= g = mx >>= (\x -> (f x >>= g))bind を使ってモナディック関数を直列につなぐ書き方を、モナディックスタイルと呼ぶ。
do
x1 <- m1
x2 <- m2
...
xn <- mn
f x1 x2 ... xnアプリカティブ
アプリカティブは、モナディック関数を並列に組み合わせられるものである。ファンクタをさらに抽象化した概念である。apply(<*>)を使ってモナディック関数を並列に組み合わせる書き方を、アプリカティブスタイルと呼ぶ。
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
pure g <*> x1 <*> x2 <*> ... <*> xnアプリカティブを使うと、複数のエラーを同時に扱える。
モナドとアプリカティブの違いについては、Monad は継続、Applicative は並列も参考になる。