在单子变换器中,我们有
instance (Monad m, Monoid e) => MonadPlus (ExceptT e m)
在可扩展效果中,没有这样的东西
instance (Monoid e) => MonadPlus (Eff (Exc e :> r))
我试过实现它,但徒劳无功。这是我到目前为止所拥有的:
instance (Monoid e) => MonadPlus (Eff (Exc e :> r)) where
mzero = throwExc mempty
a `mplus` b = undefined $ do
resultA <- runExc a
case resultA of
Left l -> runExc b
Right r -> return $ Right r
有2个问题:
对于
mzero
,GHC 抱怨如下:Could not deduce (Monoid e0) arising from a use of ‘mempty’ from the context (Monad (Eff (Exc e :> r)), Monoid e)
为什么 GHC 不
e0
匹配e
?答案(在评论中提供):开启
ScopedTypeVariables
for
mplus
,undefined
应该换成 的反函数runExc
,但是在extensible-effects的API中找不到。我错过了什么 ?
理由:我希望能够在a <|> b
范围内写作Member (Exc e) r => Eff r a
,意思是:
- 尝试
a
- 如果
a
抛出ea
,尝试b
- 如果
b
抛出eb
,则抛出mappend ea eb
这需要一个Alternative
实例,这就是为什么我MonadPlus
首先尝试实现一个实例。
注意:我使用的是 GHC 7.8.3 。
预先感谢您的帮助。