【发布时间】:2014-11-11 23:13:14
【问题描述】:
在monad transformers,我们有
instance (Monad m, Monoid e) => MonadPlus (ExceptT e m)
在extensible effects中,没有这样的东西
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
有两个问题:
-
对于
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 对于
mplus,undefined应该换成runExc的反函数,但是在extensible-effects的API中找不到。我错过了什么吗?
基本原理:我希望能够在Member (Exc e) r => Eff r a内写a <|> b,意思是:
- 试试
a - 如果
a抛出ea,试试b - 如果
b抛出eb,则抛出mappend ea eb
这需要一个Alternative 实例,这就是为什么我首先尝试实现一个MonadPlus 实例。
注意:我使用的是 GHC 7.8.3。
提前感谢您的帮助。
【问题讨论】:
-
“为什么 GHC 不匹配 e0 和 e” - 打开
ScopedTypeVariables。 -
@user2407038 确实解决了第一个问题,谢谢!
标签: haskell monadplus effect-systems