TL; DR:歷史原因。在MonadPlus
中這樣設想,後來得到了其Applicative
變體Alternative
,並且沒有人提議將Alternative
分成AZero
和AChoice
或類似的。
Alternative
是相對新的想法,就像Applicative
。當guard
第一次被設想時,它是基於MonadPlus
,Monad
,它應該支持選擇和失敗,就像Alternative
一樣。它的原始類型是這樣
那是在哈斯克爾98報告,其中
MonadPlus
已經提到指定
guard :: MonadPlus m => Bool -> m()
。順便說一句,Haskell 1.0根本不使用monad。當Applicative
終於得到了Monad
的超類,Alternative
得到MonadPlus
和mzero = empty
和mplus = (<|>)
的超類。
那麼,現在我們知道爲什麼guard
使用Alternative
。因爲它預先根據MonadPlus
。那麼爲什麼MonadPlus
這樣定義?
爲了從1998年開始獲得他們的理由,人們不得不寫一封郵件給SPJ或委員會的其他人,因爲僅僅一年後,Erik Meijer and Graham Hutton wrote their "Monadic Parsing in Haskell"文件。如果你看一下紙,你會發現,他們的MonadPlus
只是就像你打算:
class Monad m => MonadZero m where
zero :: m a
class MonadZero m => MonadPlus m where
(++) :: m a -> m a -> m a
所以它肯定可以處理您在這個「能夠停止」的方式描述它。但是,根本沒有base
類,該類當前定義了empty
而沒有Alternative
。可能有一個,但尚未提出。
請注意,這是Haskell類重複出現的主題。 Monoid
包含mappend
和mempty
。在它的概念之後,有人注意到有某些類型mappend
有意義,但不是mempty
。例如
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
顯然是聯想,而空Min
是不可能的,如果我們只是用Ord
,我們將不得不使用Bounded
。這就是爲什麼現在有Semigroup
,它不是Monoid
的基類,但給了我們這種關聯操作。
回來你原來的問題:guard
使用Alternative
,因爲Alternative
提供empty
,並且在某些Alternative
的empty
「停止」的評價。沒有其他類包含,但。
但是有了一個提案,雖然我不確定社羣對拆分Alternative
的意見是什麼。
順便說一句,像PureScript語言分裂Alternative
,雖然他們反過來...
拆分它更多有關Alternative
,爲什麼我用Monoid
再舉一個例子,看到Confused by the meaning of the 'Alternative' type class and its relationship to other type classes。
你也需要'純'。當然,你可以有一個'Pure'類提供'pure',一個'Empty'類提供'empty',並且'Alternative'需要兩個。但是,出於實用的原因,並不總是將一個類分成單一類的類。 – chi
這種情況下的實際或歷史原因? – gallais
我認爲這是因爲沒有類型,它可以實現'空'並且不能實現'(<|>)'。因此,類型類Stoppable的理論將等於Alternative。(類型集合將相等)。 – freestyle