将 monad 转换为 IO

convert monad to IO

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

但是,我想使用的操作基于与 IO(即 Servant's ClientM)不同的 monad。

我知道 liftIO,但这似乎适得其反 -- IO a -> m a

如何将我的 monad 转换为 IOs,或提升 finally 以便对我的 monad 进行操作?

请注意 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 as finally.

中定义

似乎 ClientM 在某些时候必须是 运行 和 runClientM,这导致 IO

也许最简单的解决方案(如果恰好适合您的情况)是使用 finally 包装生成的 IO 操作。