モナド (プログラミング)
fmap : ( A → B ) → ( ( S → A ) × S ) → ( S → B ) × S = f ↦ ( f ′ , s ) ↦ ( f ∘ f ′ , s ) {\displaystyle {\text{fmap}}:(A\rightarrow B)\rightarrow ((S\rightarrow A)\times S)\rightarrow (S\rightarrow B)\times S=f\mapsto (f',s)\mapsto (f\circ f',s)}
duplicate : ( ( S → A ) × S ) → ( S → ( ( S → A ) × S ) ) × S = ( f , s ) ↦ ( ( s ′ ↦ ( f , s ′ ) ) , s ) {\displaystyle {\text{duplicate}}:((S\rightarrow A)\times S)\rightarrow (S\rightarrow ((S\rightarrow A)\times S))\times S=(f,s)\mapsto ((s'\mapsto (f,s')),s)}
で定義される。
duplicate : W A → W W A = extend id {\displaystyle {\text{duplicate}}:\mathrm {W} \,A\rightarrow \mathrm {W} \,\mathrm {W} \,A={\text{extend}}\,{\text{id}}}
extend : ( W A → B ) → W A → W B = f ↦ ( fmap f ) ∘ duplicate {\displaystyle {\text{extend}}:(\mathrm {W} \,A\rightarrow B)\rightarrow \mathrm {W} \,A\rightarrow \mathrm {W} \,B=f\mapsto ({\text{fmap}}\,f)\circ {\text{duplicate}}}
で与えられる。
モナドが副作用を表現すると言われているのに対して、コモナド W は一種の「文脈」を表している。extract は文脈から値を取り出す関数である。extend は型 W A → B を持つ「文脈依存の関数」を合成してパイプラインを作る。
安全な割り算の結果は、値が Nothing であるかを素直に確認せずに(つまり割り算の結果があるかを確認せずに)そのまま計算に使えたほうが便利なことがある。これは「持ち上げ(英語版)」関数を使うことで可能である。この関数は Maybe に限定されず、任意のモナドに対して定義される。Haskellでは LiftM2 と呼ばれる。
関数型を示す矢印が右結合であることから、liftM2は2引数の関数を引数に取って、さらなる2引数の関数を返す。型シグネチャは m がモナドのとき、任意の2引数関数を「持ち上げ」ることができることを示している。例えば、
は演算子 (.*.) を定義し、それは引数がどちらも Nothing でないときに、掛け算した結果を返す(どちらかが Nothing の場合は Nothing を返す)。この方法の利点はモナドの実装に深入りする必要がないことである。他の同じような関数やモナドを使う場合でも、liftM2 を使うことで、やりたいことが鮮明になる(コードの再利用を見よ)。