簡體   English   中英

MonadPlus IO 不是幺半群

[英]MonadPlus IO isn't a monoid

Instance MonadPlus IO是獨一無二的,因為mzero拋出:

Prelude Control.Monad> mzero
*** Exception: user error (mzero)

因此, MonadPlus IO意味着它也適用於錯誤。

如果其他操作沒有拋出,則mzero顯然用作標識元素:

Prelude Control.Monad> mzero `mplus` return 0
0
Prelude Control.Monad> return 0 `mplus` mzero
0

但是當兩個動作都拋出時它不會:

Prelude Control.Monad> fail "Hello, world!" `mplus` mzero
*** Exception: user error (mzero)
Prelude Control.Monad> mzero `mplus` fail "Hello, world!"
*** Exception: user error (Hello, world!)

所以MonadPlus IO不是幺半群。

如果當用戶MonadPlus出錯時它違反了MonadPlus法律,它實際上是為了什么?

mplus下的IO是相對於標識異常的等價類的幺半群。 不是那么令人滿意。 另一種方法可能如下所示:

m <|> n = m `catches`
  [ Handler $ \ ~EmptyIO -> n
  , Handler $ \ ~se@(SomeException _) ->
      n `catch` \ ~EmptyIO -> throwIO se ]

這種方法的主要問題是處理程序可以堆疊。 當第一個動作失敗時,我們不能只承諾第二個動作。 一個較小的問題是沒有完全可靠的方法來確定異常是同步的(並且應該使用throwIO重新拋出)還是異步的(在這種情況下我們需要使用throwTo和我們自己的線程 ID 重新拋出它)。 所以這種方式是一團糟。

暫無
暫無

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

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