私は両方に非常に慣れていないMonads
とMonoids
について最近知りましたMonadPlus
。私が見たところ、Monoid
どちらMonadPlus
も連想二項演算とアイデンティティを備えた型を提供しています。(私はこれを数学用語で半群と呼びます。) では、 と の違いは何Monoid
ですかMonadPlus
?
3 に答える
半群とは、連想二項演算を備えた構造体です。モノイドは、二項演算の恒等元を持つ半群です。
モナドと半群
すべてのモナドはモナドの法則に従う必要があります。私たちの場合、重要なのは結合法則です。を使用して表現>>=
:
(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
この法則を適用して の結合性を導き出しましょう>> :: m a -> m b -> m b
:
(m >> n) >> p ≡ (m >>= \_ -> n) >>= \_ -> p
≡ m >>= (\x -> (\_ -> n) x >>= \_ -> p)
≡ m >>= (\x -> n >>= \_ -> p)
≡ m >>= (\x -> n >> p)
≡ m >> (n >> p)
( 、またはx
に表示されないように選択した場所)。m
n
p
>>
型に特化するとm a -> m a -> m a
( を代入b
してa
)、任意の型a
に対して操作>>
が 上の半群を形成することがわかりますm a
。これは任意の に当てはまるため、a
によってインデックス付けされた半群のクラスを取得しますa
。ただし、それらは一般にモノイドではありません - の恒等要素はありません>>
。
MonadPlus とモノイド
MonadPlus
さらに 2 つの操作を追加mplus
しmzero
ます。MonadPlus
法則は明示的に述べてmplus
おり、任意の に対してmzero
モノイドを形成しなければなりません。再び、 によってインデックス付けされたモノイドのクラスを取得します。m a
a
a
と の違いに注意してくださいMonadPlus
:Monoid
はMonoid
、ある単一の型がモノイド規則を満たしてMonadPlus
いることを示していますが、可能なすべてa
の型について、その型がモノイド規則を満たしていることを示していm a
ます。これははるかに強い条件です。
したがって、MonadPlus
インスタンスは 2 つの異なる代数構造を形成します。半群のクラスとと>>
のモノイドのクラスです。(これは珍しいことではありません。たとえば、ゼロより大きい自然数の集合は、とで半群を形成し、と でモノイドを形成します。)mplus
mzero
{1,2,...}
+
×
1
それが成立する場合、は aであるMonadPlus m
と言えますが、(型 "関数" に適用した結果の型) はモノイドです。m
Monad
m a
a
m
を定義すると ( の定義に似てData.Monoid
いますが、後でこれを利用します)
class Semigroup a where (<>) :: a -> a -> a
class Semigroup a => Monoid a where zero :: a
それからそれは持っています
mzero :: MonadPlus m => m a
mplus :: MonadPlus m => m a -> m a -> m a
かなり類似した型と適切な法則
-- left and right identity
mplus a mzero == a
mplus mzero a == a
-- associativity
(a `mplus` b) `mplus` c == a `mplus` (b `mplus` c)
Monoid
を使用すれば、Haskell を定義することもできます-XFlexibleInstances
{-# LANGUAGE FlexibleInstances #-}
instance MonadPlus m => Semigroup (m a) where (<>) = mplus
instance MonadPlus m => Monoid (m a) where zero = mzero
これらは のインスタンスと重なっていますがData.Monoid
、これがおそらく標準インスタンスではない理由です。
このようなモノイドの別の例は、Alternative m => m a
からのものControl.Applicative
です。
非常に重要な違いを強調しなければなりません。モノイドとは異なり、他の回答の状態とは異なり、MonadPlus はそうではありません。関連二項演算と ID を持つ型を提供します。標準のステータスを主張できる唯一のドキュメントである Haskell Report は、MonadPlus の法則を指定していないため、mplus が連想であることや、mzero が左または右の単位であることを要求していません。おそらく、著者たちはまだ法則について議論していたのでしょう: mplus が結合的でないのには十分な理由があります。たとえば、mplus が結合的で可換でない場合、MonadPlus によって表される非決定論的検索計算は完了できません (つまり、見つけられない解が存在します)。mplus が可換であることは非常にまれであるため、結合性を主張する場合、完全な非決定論的検索手順を MonadPlus で表すことはできません。SC に関する MonadPlus の法則のまさにこの問題について、詳細な議論が行われました。mplus は常に関連付けられている必要があります