簡體   English   中英

“除了”的復雜性在Haskell中的作用是什么?

[英]What purpose does the complexity of `Except` serve in Haskell?

理解 (我認為)在Haskell中EitherExcept之間存在密切關系,並且很容易從一個轉換為另一個。 但是我對在Haskell中處理錯誤的最佳實踐以及在什么情況和情況下我會選擇其中一個而感到困惑。 例如,在Control.Monad.Except提供的示例中,在定義中使用了Either

type LengthMonad = Either LengthError

所以calculateLength "abc"

Right 3

相反,如果要定義

type LengthMonad = Except LengthError

然后calculateLength "abc"將是

ExceptT (Identity (Right 3))

我很困惑這會起什么作用,何時需要它。 為什么從calculateLength返回的所有內容總是具有Identity ; 為什么不只是SomeExceptionType (Right 3)甚至SomeSuccessType 3

當談到像這樣的概念時,我是一個Haskell的初學者,所以當我希望后者超過前者時,我會非常感激,特別是為什么它(顯然對我來說)很復雜。 例如,使用Except calculateLength版本的函數的調用者可以做什么,他們不能(或至少不能那么容易)使用Either版本?

抽象

Either用於正常成功/錯誤 API。 它在基礎庫中定義,因此不會將其他依賴項推送到使用者身上。 此外,這是最基本的Haskell類型之一,因此'每個人'都了解它的工作原理。

如果您特別需要將Either與另一個monad(例如IO )組合,則僅使用ExceptT 此類型在變換器庫中定義,因此會對消費者產生額外的依賴性。 另外,monad變換器是Haskell的一個更高級的功能,所以你不能指望每個人都能理解如何使用它。

對原因的猜測

做出這些決定時,我並不在身邊,但似乎有各種歷史原因引起混淆 Haskell是一種古老的語言(比Java早!),所以即使已經努力簡化它並糾正舊的錯誤,一些仍然存在。 據我所知, Either / ExceptT混淆是其中一種情況。

猜測 Either比monad變換器的概念要老,所以我想在早期的Haskell歷史中將類型Either引入基礎庫。

Maybe似乎也是如此。

其他monad,例如ReaderState似乎已經與他們的monad變換器一起被引入(或至少'retconned')。 例如, Reader只是ReaderT一個特例 ,其中'其他' MonadIdentity

type Reader r = ReaderT r Identity

StateT

type State s = StateT s Identity

這是變形金剛庫中定義的許多monad的一般模式。 ExceptT只是遵循模式,將Except定義為ExceptT

這種模式有例外。 例如, MaybeT沒有將Maybe定義為特例。 我再次相信這是出於歷史原因; Maybe很久很久才有人開始研究變形金剛圖書館。

關於Either的故事似乎更令人費解。 據我所知, ,原來,一個EitherT單子轉換,但顯然(我忘了細節)有一些錯誤的方式,它的表現(它可能打破了一些法律),因此,它與另一變壓器更換叫做ErrorT ,后來又證明是錯的。 我想,第三次是魅力,所以引入了ExceptT

Control.Monad.Trans.Except模塊遵循大多數其他monad變換器的模式,通過使用類型別名定義'無效'特殊情況:

type Except e = ExceptT e Identity

我想這樣做是因為它可以,但它可能是不幸的,因為它令人困惑。 絕對現有技術表明monad變換器不必遵循該模式(例如MaybeT ),所以我認為如果模塊沒有這樣做會更好,但確實如此,那就是我們所處的位置。

我基本上會忽略Except類型並使用Either代替,但如果需要變換器則使用ExceptT

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM