[解決済み] MonadPlus, Alternative, Monoidの型別は?
質問
標準ライブラリHaskell型クラス
MonadPlus
,
Alternative
そして
Monoid
はそれぞれ本質的に同じセマンティクスを持つ2つのメソッドを提供します。
-
空の値。
mzero
,empty
またはmempty
. -
演算子
a -> a -> a
は,型クラス内の値を結合する演算子である。mplus
,<|>
またはmappend
.
3つとも、インスタンスが遵守すべきこれらの法則を規定しています。
mempty `mappend` x = x
x `mappend` mempty = x
このように,3つの型クラスはいずれも と同じ メソッドを提供しているようです。
(
Alternative
もまた
some
と
many
がありますが、通常はそれらのデフォルトの定義で十分なので、この質問の観点ではあまり重要ではありません)。
私の疑問は、なぜこれら 3 つの非常によく似たクラスがあるのか、ということです。スーパークラスの制約が異なる以外に、これらの間に何か本当の違いがあるのでしょうか?
どのように解決するのですか?
MonadPlus
そして
Monoid
は異なる目的で使用されます。
A
Monoid
は、ある種の型に対してパラメータ化された
*
.
class Monoid m where
mempty :: m
mappend :: m -> m -> m
というように、連想可能で単位を持つ明白な演算子が存在する、ほとんどすべての型に対してインスタンス化することができます。
しかし
MonadPlus
はモノイダル構造を持つことを指定するだけでなく、その構造が、どのように
Monad
がどのように機能するかに関係します。
と
は、その構造がモナドに含まれる値を気にしないことを、これは(部分的に)示しています。
MonadPlus
は引数として
* -> *
.
class Monad m => MonadPlus m where
mzero :: m a
mplus :: m a -> m a -> m a
モノイドの法則に加え、以下の2つの法則を適用することができます。
MonadPlus
. 悲しいことに、コミュニティはそれらが何であるべきかについて意見が一致していません。
少なくとも、私たちは
mzero >>= k = mzero
という拡張がありますが、他に左(sic)分配法則という競合する拡張があります。
mplus a b >>= k = mplus (a >>= k) (b >>= k)
と左のキャッチフレーズ
mplus (return a) b = return a
というわけで、どのインスタンスも
MonadPlus
のインスタンスは、これらの追加的な法則の一つまたは両方を満たす必要があります。
では
Alternative
?
Applicative
の後に定義されました。
Monad
の上位クラスとして定義され、論理的には
Monad
に属するものですが、Haskell 98 のころの設計者に対するさまざまな圧力のためか、この
Functor
のスーパークラスではありませんでした。
Monad
のスーパークラスではありませんでした。今、私たちはついに
Applicative
のスーパークラスとして
Monad
のスーパークラスとしてGHCに追加されました(言語標準にはまだないようです)。
効果的に
Alternative
は
Applicative
何
MonadPlus
になります。
Monad
.
この場合、次のようになります。
empty <*> m = empty
と同じように
MonadPlus
であり、同様の分配性と捕捉性が存在し、そのうちの少なくとも1つは満たす必要があります。
残念ながら、たとえ
empty <*> m = empty
の法則は強すぎる主張です。それは
後方
には当てはまりません。
MonadPlusを見ると、空 >>= f = 空の法則がほぼ強制されています。空の構成は、関数を呼び出すために、その中にいかなる'a'も持つことができません。
f
を呼び出すことができません。
しかし
Applicative
は
ではなく
のスーパークラスです。
Monad
と
Alternative
は
ではない
のスーパークラスです。
MonadPlus
のスーパークラスではないので、両方のインスタンスを別々に定義することになります。
さらに、たとえ
Applicative
がスーパークラスであったとしても
Monad
のスーパークラスであれば、結局は
MonadPlus
クラスに従ったとしても
empty <*> m = empty
ということを証明するには、厳密には十分ではありません。
empty >>= f = empty
つまり、何かを主張することは
MonadPlus
であると主張するよりも
Alternative
.
さて、慣例により
MonadPlus
と
Alternative
は一致するはずですが
Monoid
は
完全に
は異なるかもしれません。
例えば
MonadPlus
と
Alternative
に対して
Maybe
当たり前のことを当たり前にやる。
instance MonadPlus Maybe where
mzero = Nothing
mplus (Just a) _ = Just a
mplus _ mb = mb
が、その
Monoid
インスタンスは半グループを
Monoid
. 悲しいことに
Semigroup
クラスが存在しなかったため、Haskell 98 では、このクラスは
Monoid
を要求しますが、その単位は使いません。ಠ_ಠ
instance Monoid a => Monoid (Maybe a) where
mempty = Nothing
mappend (Just a) (Just b) = Just (mappend a b)
mappend Nothing x = x
mappend x Nothing = x
mappend Nothing Nothing = Nothing
TL;DR
MonadPlus
よりも強い主張です。
Alternative
よりも強い主張であり、さらに
Monoid
であり、一方
MonadPlus
と
Alternative
のインスタンスは関連しているはずです。
Monoid
は全く別のものである可能性があります(時にはそうである場合もあります)。
関連
-
[解決済み】Haskellでの挿入ソート
-
[解決済み] 一般的に `{- |` で始まるHaskellのコメントは何を意味するのですか?
-
[解決済み] haskellにおけるdrop関数 - リスト内包を用いた実装
-
[解決済み] Haskellバイナリツリー
-
[解決済み] .の違いは何ですか?(ドット)と$(ドルマーク)の違いは何ですか?
-
[解決済み] Haskellは実世界で何に使われているのか?[クローズド]
-
[解決済み] Haskellにおける "リフティング "とは?
-
[解決済み] Haskellの「何もしない」関数、idはなぜ大量のメモリを消費するのか?
-
[解決済み] Haskellのドット演算子:もっと説明が欲しい
-
[解決済み] Haskellのストリクトネスポイントは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン