Monoid 大集合
以下のような共通の性質をもつ関数が存在する。
- 関数は引数を2つとる
- 2つの引数および返り値の型はすべて等しい
- 2引数関数を施して相手を変えないような特殊な値が存在する
++
なら空リスト*
なら1
- 例:
x * 1
,"hoho" ++ []
例
*Main> (3 * 2) * (8 * 5) 240 *Main> 3 * (2 * (8 * 5)) 240 *Main> "la" ++ ("di" ++ "ga") "ladiga" *Main> ("la" ++ "di") ++ "ga" "ladiga"
この性質を 結合的(associativity)
という。
++
や *
が当てはまる。
-
は当てはまらない。
*Main> (5 - 3) - 4 -2 *Main> 5 - (3 - 4) 6
Monoid 型クラス
モノイドは、結合的な二項演算子(2引数関数) と、その演算に関する単位元からなる構造である。
ある値がある演算の単位元である。とは、 その値となにか他の値を引数にしてその演算を呼び出した時、 返り値が常に他の値のほうに等しくなる。 ということ
1
は*
の単位元である。[]
は++
の単位元である。
以下は Monoid の定義
class Monoid m where mempty :: m mappend :: m -> m -> m mconcat :: [m] -> m mconcat = foldr mappend mempty
Monoid のインスタンスになれるのは具体型のみ
mempty
は、そのモノイドの単位元を表す。
mappend
は、モノイド固有の二項演算。
同じ型の引数を2つ取り、その型の別の値を返す。
append
という関数名から連想される付け加えるというイメージは捨てること。
mconcat
は、モノイドのリストをとって、mappend
を間に挟んだ式を作り、
単一の値を計算してくれる関数。
デフォルト実装がついており、たいていの場合これで事足りる。
自分で Monoid型クラスのインスタンスを作るときも、
mempty
と mappend
だけ実装すればだいたい動く。
モノイド則
Monoid インスタンスは次の法則を満たさなければならない
1
mempty `mappend` x = x
2
x `mappend` mempty = x
3
(x `mappend` y) `mappend` z = x `mappend` (y `mappend` z)
1つ目と2つ目は、mempty
が mappend
に関して単位元として振る舞う必要があることを述べている。
3つ目は、mappend
が結合的であることを述べている。
所感
いきなり単位元という言葉が登場して面食らったが、 ファンクターと同じようにこういう構造を持ったデータ型を作りたい時に使うんだな。たぶん。 モノイド を使うとなにが嬉しいのかはこれからわかるのであろう。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る