前置き
記事の修正点は、真摯に対応いたします。
よろしくお願いします。
モナドとは
関数型プログラミング上では、「クライスリ圏」における3則を満たすもののこと…
ってもっと簡単に(笑)
プログラミングが分かる人向けの説明にすると…
ある値を状態として保持しておくことの出来る計算機構を、
その言語や環境内部に実装したもの…
と言い換えると、あれってなる人はお察しの通り、
チューリング完全
ってやつです。
モナドの使い方
ある計算機構がモナドである場合、以下の関数を内部に保持しています。
- of
- bind
- join
of
計算機構に対して値を代入します。
言語によっては構造体やオブジェクト、関数なども代入できます。
Monad.of({a: 1})
又は単なる関数実行の場合もあります。
(本記事では、以後こちらを使います。)
Monad({a: 1})
join
計算機構から値を取り出します。
Monad({a: 1}).join() //{a: 1}が返る
実装によっては、単なる get の場合もあります。
(本記事では、以後こちらを使います。)
Monad({a: 1}).join //{a: 1}が返る
bind
モナドを返す関数 f を引数に取って、f(x) の冒頭の引数に保持している値を
代入します。
関数の返値をモナドの中に再代入しますが、この時そのまま代入すると…
Monad(Monad(...)).join.join
になってしまうので、内部で値を1段階裸にします。
これにより、副作用を隠蔽しているわけです。
しかも、モナドが返っているので連続的に記述できます。
Monad({a: 1})
.bind(o => Monad({a: o.a + 5}))
.bind(o => Monad({a: o.a * 5}))
.join
//{a: 30}になってる!!!
何が凄いのか?
最大のメリットは、抽象化された無名関数を代入するので、命名に悩まされないと言えるでしょう。
以下に、メリットをまとめます。
- 命名なしに処理をまとめて記述出来る。
- オブジェクトのメソッドに返り値がない場合でも、連続的に書ける。
- 処理をまとまり毎に記述できる。
おまけ
モナドはfunctor(関手)の機能を内在していることがほとんどです。
引数にとった関数の冒頭の引数に保持している値を代入するのはbindと同じです。
Functor({a: 1}).map(o => o.a === 1).value // true
Monad({a: 1}).map(o => o.a === 1).join // true
モナドの作り方について
モナドを作る際の事については、以下にまとめます。
恒等モナドで分かる、モナドの作り方入門
最後までお読みいただき、ありがとうございました。