【发布时间】:2014-12-18 18:21:18
【问题描述】:
我有一个并发助手,它是IO 的一个小包装。对它来说,>>= 与原版的IO 一样是顺序的,但>> 会同时执行它的参数。
我想让这种类型成为MonadThrow 的实例(来自exceptions 包)。但是,文档中说 MonadThrow 必须满足的这条法律让我停顿了一下:
throwM e >> x = throwM e
我的 monad 并非完全如此。由于throwM e 和x 将同时执行,x 可以在外部世界产生影响,甚至在throwM e 中断计算之前抛出它自己的异常。
能否以“宽松”的方式解释法律,还是我应该避免编写 MonadThrow 实例?
编辑。这是我的 Monad 的简化代码:
import Control.Concurrent.Async(concurrently)
newtype ConcIO a = ConcIO { runConcIO :: IO a }
instance Monad ConcIO where
return = ConcIO . return
f >>= k = ConcIO $ runConcIO f >>= runConcIO . k
f >> k = ConcIO $ fmap snd $ concurrently (runConcIO f) (runConcIO k)
【问题讨论】:
-
这是否意味着
a >> b = a >>= \ _ -> b不再成立? -
@augustss 嗯,这是另一个担心。我不确定我的类型是否真的是单子。如果没有异常发生,
a >> b的返回值将等于a >>= \_ -> b的返回值。但是在我的 monad 中b可能会在a完成之前产生影响并抛出异常......
标签: exception haskell concurrency monads