将Monad转换为IO

4

我想使用finally,签名为IO a -> IO b -> IO a

然而,我想要使用的操作基于一个与IO不同的单子(即ServantClientM)。

我知道liftIO,但似乎它做的是相反的事情--IO a -> m a

我该如何将我的单子转换为IO,或者提升finally以便在我的单子上操作?

2个回答

9
注意,ClientM也有一个MonadBaseControl IO ClientM实例,用于处理这种情况。例如,我认为以下内容应该可以通过类型检查(并且可以与m ~ ClientM一起使用)。
finally' :: MonadBaseControl IO m => m a -> m b -> m a
finally' x y = control $ \runInIO -> catch (runInIO x) (runInIO y)

编辑

上面的代码不仅进行了类型检查,而且在lifted-base中定义为finally


1
感谢你的帮助!我会迷失在寻找这个黑魔法的路上。然而,当我尝试使用 MonadBaseControl 实例时,我遇到了一个错误 - 我已经在这里发布了一个新的问题 here - Kiara Grouwstra

1
似乎必须在某个时刻使用runClientM运行ClientM,将其降级为IO
如果适用于您的情况,最简单的解决方案可能是使用finally包装该结果的IO操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接