モナド (プログラミング)
fmap : ( A → B ) → ( M → A ) → M → B = f ↦ g ↦ ( f ∘ g ) {\displaystyle {\text{fmap}}:(A\rightarrow B)\rightarrow (M\rightarrow A)\rightarrow M\rightarrow B=f\mapsto g\mapsto (f\circ g)}
duplicate : ( M → A ) → M → ( M → A ) = f ↦ m ↦ m ′ ↦ f ( m ∗ m ′ ) {\displaystyle {\text{duplicate}}:(M\rightarrow A)\rightarrow M\rightarrow (M\rightarrow A)=f\mapsto m\mapsto m'\mapsto f\,(m*m')}
で定める。εと * はモノイド M {\displaystyle M} の単位元と二項演算子である。
この過程は時相論理において宣言的な命題のみで時間の経過を表現する手法と似ている。以下の例ではプログラム内のアクションを連鎖する方法の詳細を再び Haskell を使って明らかにする。
基本的な種類の入出力操作、標準出力に文字列を書く、標準入力から文字列を読む、ファイルの読み書き、ネットワーク越しのデータ送信等をすべて記述できるようにしたい。さらに、これらのプリミティブを組み合わせて大きなプログラムを作れる必要もある。例えば次のように書けることが望ましい。
この直観的な記法はどのように形式化できるだろうか?このためには各入出力アクションに対して、いくつかの基本的な操作を実行できる必要がある。
ふたつの入出力アクションをひとつにできなければならない。Haskellでは、中置演算子 >> を用いて、putStrLn "abc" >> putStrLn "def" と書き、コンソールに二行の文字列を表示するひとつのアクションである。演算子 >> の型は IO a → IO b → IO b であり、ふたつの入出力アクションを引数に取り、順番に実行するひとつのアクションにまとめて返す。
何もしないという入出力アクションも必要である。これは値を返すがなんの副作用も持たない。Haskellではこのアクションは return で構築され、この型は a → IO a である。
さらに、最初のアクションの結果に基づいて次に実行するアクションを決める必要がある場合がある。Haskellでは、演算子 >>= (bindと読む)を使い、型は IO a → (a → IO b) → IO b である。