2017-06-22 4 views
6

なぜguardに基づいてAlternative`guard`は` Alternative`に基づいているのはなぜですか?

guard :: Alternative f => Bool -> f() 
-- guard b is pure() if b is True, 
-- and empty if b is False. 

guardのみAlternativeからemptyを使用していますので、私は尋ねます。 <|>Alternativeからまったく使用していません。だからなぜ最初にAlternativeを使用して気にしていますか?

私たちは(Trueに引き続き、Falseに停止)guardを達成しようとしているものと完全に一致するAlternativeさんemptyの背後にあるいくつかの暗黙の考え方があるので、これはあると思います。このような場合は、この無言のアイデアについて私に教えてください。

同時に、私たちがちょうど無視していると感じたら、<|>。それはほぼがすべてについて約guardが「完全にキャプチャしていない」ように感じます。私はそれが理にかなったことを願うもっと具体的にするには:Stoppable(またはAbortable)のような別のタイプのクラスを作成して、なぜそれをAlternativeの代わりに使用しなかったのですか?

+2

また、「純粋」が必要です。確かに、純粋なクラスを提供する 'Pure'クラスと空のクラスを提供する' Empty'クラスを持ち、 'Alternative'を両方とも必要とすることができます。しかし、実用的な理由から、クラスを必ずしも単一メソッドクラスに分割するわけではありません。 – chi

+1

この場合、現実的または歴史的な理由はありますか? – gallais

+1

型がないので、 '空'を実装でき、 '(<|>)'を実装できないと思います。したがって、理論的には、タイプクラス「ストップ可能」は「代替」と等しくなります(タイプのセットは等しくなります)。 – freestyle

答えて

8

TL; DR:歴史的な理由。これはの亜種Alternativeになりました。AlternativeAZeroAChoiceまたはそれに類するものに分割することを提案していない人はMonadPlusでこのように考えられました。


AlternativeだけApplicativeのように、比較的新しいアイデアです。 guardが最初に構想されたときには、それは、Monadに基づいていました。これは、選択と失敗をサポートする必要があります。Alternativeと同じです。その元の型は、このようにMonadPlusが既に指摘されたHaskellの98のレポートで指定された

guard :: MonadPlus m => Bool -> m() 

ました。ハスケル1.0は、まったくモナドを使用しませんでした。 Applicativeが最終的にMonadのスーパークラスを得たとき、AlternativeMonadPlusのスーパークラスとなり、mzero = emptymplus = (<|>)のスーパークラスを得ました。

なぜ、guardAlternativeを使用する理由がわかりました。あらかじめMonadPlusに基づいていたので。では、なぜMonadPlusがこのように定義されていますか?

わずか1年後、Erik Meijer and Graham Hutton wrote their "Monadic Parsing in Haskell"紙のため、SPJや委員会の他の誰かから、1998年の理由を説明するためにメールを書く必要がありました。

class Monad m => MonadZero m where 
    zero :: m a 

class MonadZero m => MonadPlus m where 
    (++) :: m a -> m a -> m a 

だから、それはあなたがしました。この「停止可能」な方法を処理するために、確かに可能です:あなたは紙を見てみると、あなたが意図するようそのMonadPlusだけで動作することがわかりますそれを説明した。ただし、現在のところemptyを定義しているbaseクラスはありません。Alternativeはありません。 1つはあるかもしれないが、まだ提案されていない。

これはHaskellクラスを使用した定期的なテーマです。 Monoidは、mappendおよびmemptyを含む。その受胎後、ある人は、mappendが意味を持つが、memptyではない特定のタイプがあることに気づいた。空Minは我々だけOrdを使用している場合、我々はBoundedを使用しなければならないことは不可能であるのに対し、例えば、ここで

newtype Min a = Min a 

combine :: Ord a => Min a -> Min a -> Min a 
combine (Min x) (Min y) = Min (min x y) 

について、mappend = combineは、明確に連想です。だから今はSemigroupがあります。これはまだMonoidの基本クラスではありませんが、それは連想操作です。戻ってあなたの元の質問に来て

guardAlternativeemptyを提供するので、Alternativeを使用し、empty特定Alternative年代の評価「が停止し」。それ以外のクラスはありません。まだです。

しかし、提案では、私は分けることに関するコミュニティの意見は何か分かりませんが、ある時点であるかもしれません。Alternativeです。ところで

は、彼らが他の方法でラウンドそれを分割するものの、PureScriptのような言語はAlternative詳細については...、

Alternativeを分割し、私は別の例としてMonoidを使用する理由、Confused by the meaning of the 'Alternative' type class and its relationship to other type classesを参照してください。

+1

私はそれが見落としであるとは言いません。粒度と凝集力との間に正当な設計上のトレードオフがあります。私は個人的には、Haskellのクラス階層をPureScriptのものにいくぶん優先しています。 「空」と「<|>」は自然に「一緒に」行く。 –

+1

@BenjaminHodgson私は判断を削除しましたが、それは本当に適切ではありませんでした。 – Zeta

+1

'MonadFail'について考える価値もあります。' MonadFail'の 'fail'は' empty'のようなものですが、復帰ではなく '>> ='で空を拡張します。 – dfeuer

関連する問題