Snap Handler编译报错Could not deduce (CI.MonadCatchIO (Handler App (AuthManager App)))如何解决
错误原因
编译报错的核心是Handler App (AuthManager App)类型没有实现Control.Monad.CatchIO提供的MonadCatchIO类型类,因此无法直接调用CI.try方法。
方案1:替换为exceptions包的try方法(推荐)
Snap框架的Handler类型默认已经实现了exceptions包提供的MonadCatch类型类,完全可以满足捕获IO异常的需求,不需要额外写实例:
- 调整导入,把
Control.Monad.CatchIO的导入替换为exceptions包的对应接口:
import qualified Control.Exception as E -- 删除原有的Control.Monad.CatchIO导入,替换为下面的 import Control.Monad.Catch (try)
- 直接替换
CI.try为try即可,其他代码无需修改:
runQuery' :: forall req accept contentType b1. (Produces req accept, MimeUnrender accept b1, Show b1, MimeType contentType) => ServicesRequest req contentType b1 accept -> Handler App (AuthManager App) (Either E.SomeException (Either MimeError b1)) runQuery' req = try $ runQuery req
方案2:手动实现MonadCatchIO实例
如果必须保留Control.Monad.CatchIO的使用逻辑,可以手动给Handler类型添加MonadCatchIO的orphan实例:
import qualified Control.Monad.CatchIO as CI import Control.Monad.Catch (catch, try) -- 注意这是orphan实例,建议放在项目统一的工具模块中,避免重复定义 instance CI.MonadCatchIO (Handler App (AuthManager App)) where catchIO = catch CI.try = try
添加实例后原有代码不需要修改即可正常编译。
注意:orphan实例存在跨模块重复定义的冲突风险,非必要不推荐使用。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

