如何使用显式模式匹配修复MonadFail (Either String)报错
问题根本原因
你修改后的代码依然没有消除do块中的可失败模式匹配,这才是触发MonadFail报错的核心原因。
你当前代码的do块第一行,左侧的(Select sl' f' w' g' d')是不完整模式:QueryExpr类型还包含UnionAll等其他构造子,GHC判定该模式存在匹配失败的可能,需要MonadFail实例处理匹配失败的分支,但Either String并未提供该实例,因此报错仍然存在。你之前的调整仅修改了绑定右侧的表达式,完全没有解决左侧模式可失败的问题,不符合显式模式匹配的修复要求。
正确修复方案
直接对slstmt做完整的显式模式匹配,完全移除do块中的可失败绑定:
applyCosPass p c (Select sl f w g d) = case slstmt of Left s -> Left s Right (Select sl' f' w' g' d') -> do nsl <- checkListErr $ map convSI sl' nf <- newFr f' nw <- newWh w' return $ Select nsl nf nw g' d' -- 补全其他构造子的处理逻辑,示例为返回错误提示,可根据业务需求调整 Right other -> Left $ "Expected Select constructor, got " ++ show other where slstmt = p c (Select sl f w g d)
其他可选临时方案
如果暂时不想修改代码逻辑,也可以通过添加编译参数兼容旧行为:在编译参数中加入-fno-warn-missing-monadfail-instances,或者在模块头部添加{-# LANGUAGE MonadFailDesugaring #-}注解,临时恢复旧版GHC的模式匹配失败降级逻辑。
内容的提问来源于stack exchange,提问作者Emma Liu
相关产品推荐
相关产品推荐

