2017-06-22 48 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只使用從Alternativeempty。它根本不使用Alternative<|>。那麼爲什麼要首先使用Alternative呢?

我想這是因爲,隨着我們試圖用guard(停止False,繼續True)完成的任務完全符合Alternativeempty背後的一些不成文的想法。如果是這種情況,請啓發我關於這個未說明的想法。

與此同時,如果覺得我們只是忽略<|>。感覺好像guard不是「完全捕獲」Alternative的全部內容。我希望這是有道理的。爲了使它更具體:爲什麼他們不發明另一個類型叫Stoppable(或Abortable),並用它來代替Alternative

+2

你也需要'純'。當然,你可以有一個'Pure'類提供'pure',一個'Empty'類提供'empty',並且'Alternative'需要兩個。但是,出於實用的原因,並不總是將一個類分成單一類的類。 – chi

+1

這種情況下的實際或歷史原因? – gallais

+1

我認爲這是因爲沒有類型,它可以實現'空'並且不能實現'(<|>)'。因此,類型類Stoppable的理論將等於Alternative。(類型集合將相等)。 – freestyle

回答

8

TL; DR:歷史原因。在MonadPlus中這樣設想,後來得到了其Applicative變體Alternative,並且沒有人提議將Alternative分成AZeroAChoice或類似的。


Alternative相對新的想法,就像Applicative。當guard第一次被設想時,它是基於MonadPlus,Monad,它應該支持選擇和失敗,就像Alternative一樣。它的原始類型是這樣

那是在哈斯克爾98報告,其中 MonadPlus已經提到指定
guard :: MonadPlus m => Bool -> m() 

。順便說一句,Haskell 1.0根本不使用monad。當Applicative終於得到了Monad的超類,Alternative得到MonadPlusmzero = emptymplus = (<|>)的超類。

那麼,現在我們知道爲什麼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包含mappendmempty。在它的概念之後,有人注意到有某些類型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,並且在某些Alternativeempty「停止」的評價。沒有其他類包含,

但是有了一個提案,雖然我不確定社羣對拆分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',它的'fail'有點像'empty',但是用'>> ='而不是恢復來擴展空虛。 – dfeuer