22

これは、設計コード、特にライブラリで何度か出てきた質問です。少し興味があるようですので、良いコミュニティ wiki になるのではないかと思いました。

Monadのfailメソッドは、いぼだと考える人もいます。元の圏論に由来しないクラスへのいくぶん恣意的な追加。しかし、もちろん現在の状態では、多くのモナド型は論理的で有用なfailインスタンスを持っています。

MonadPlus クラスは Monad のサブクラスでありmzero、モナドに失敗の概念を論理的にカプセル化するメソッドを提供します。

したがって、ある種の障害処理を行うモナド コードを書きたいライブラリ設計者は、自分のコードfailで Monad のメソッドを使用するか、自分のコードを MonadPlus クラスに制限するかを選択できmzeroます。彼はモノイド結合mplus操作をまったく気にしません。

この主題に関するいくつかの議論は、MonadPlus クラスを改革するための提案に関するこの wiki ページにあります。


だから私は1つの特定の質問があると思います:

fail自然なメソッドを持っているが、MonadPlus の論理的な実装を持たないために MonadPlus のインスタンスになれないモナドのインスタンスがあればmplus?

しかし、私は主にこの主題に関する議論に興味があります。ありがとう!


編集:最後の考えが1つ浮かびました。私は最近fail(x:xs) <- return []モナドのfail.

言語設計者はfail、Monad に含まれる Haskell の構文に組み込まれた何らかの自動障害処理の可能性に強く影響されたに違いないようです。

4

2 に答える 2

11

考えてみてくださいEither。モナドのインスタンスは次のようになります。

{-# LANGUAGE FlexibleInstances #-}
instance Monad (Either String) where
  (Left x) >>= _   = Left x
  (Right a)  >>= f = f a
  return           = Right
  fail             = Left

(のようなインスタンスを許可するには、FlexibleInstancesEither Stringが必要です)
したがって、基本的にMaybeは、何かが発生した場合にオプションのエラー メッセージが表示されるようになります。mzero失敗にエラー メッセージを追加できないため、これを で再作成することはできません。とは若干異なりfailます。

の各インスタンスは、mplus次の 2 つの法則を満たす必要があります。

mzero `mplus` a -> a
a `mplus` mzero -> a

シンプルですね。しかし、これらの法律はmplus特別なものです。それらを使用すると、適切なMonadPlusインスタンスを作成できます。

instance MonadPlus (Either a) where
  mzero = Left undefined
  mplus (Left _) b = b
  mplus a _        = a

これは何ですか?選択を表しています。最初の計算が成功すると、それが返されます。それ以外の場合mplusは、2 番目の計算を返します。(>>)法則を満たさない との違いに注意してください。

Left a   >>    Right b -> Left a
Left a `mplus` Right b -> Right b

(>>)最初の計算で停止しますが、mplus代わりに 2 番目の計算を試みます。[]また、次のように動作します。

[] >> [1..4] -> []
[] `mplus` [1..4] -> [1,2,3,4]

これは、 の側面MonadPlus、特に とmplusは対照的なの側面について説明するためのもの(>>)です。

于 2011-02-17T13:29:27.243 に答える