在单子变换器中,我们有
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?答案(在评论中提供):开启
ScopedTypeVariablesfor
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 。
预先感谢您的帮助。