如何使用显式模式匹配修复 MonadFail(任一字符串)错误
How to fix the MonadFail (Either String) Error using explicit pattern matching
我试图改编一个旧的 Haskell 项目,它现在与最新的 GHC 不兼容(MonadFail
现在是默认的)。
applyCosPass :: CosCtx a => (a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
applyCosPass p c (UnionAll q1 q2) =
UnionAll <$> applyCosPass p c q1 <*> applyCosPass p c q2
applyCosPass p c (Select sl f w g d) =
do (Select sl' f' w' g' d') <- p c (Select sl f w g d)
nsl <- (checkListErr $ map convSI sl')
nf <- newFr f'
nw <- newWh w'
return $ Select nsl nf nw g' d'
where ...
它returns错误如下:
• Could not deduce (MonadFail (Either String))
arising from a do statement
with the failable pattern ‘(Select sl' f' w' g' d')’
from the context: CosCtx a
bound by the type signature for:
applyCosPass :: forall a.
CosCtx a =>
(a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
at src/CosetteParser.lhs:(648,3)-(649,63)
• In a stmt of a 'do' block:
(Select sl' f' w' g' d') <- (case slstmt of
Left s -> error s
Right e -> Right e)
根据 Haskell Wiki 中的选项 2“Adapting New Code”,代码已修改为显式模式匹配,但错误仍然存在。这里可能缺少什么?
applyCosPass p c (Select sl f w g d) =
do {(Select sl' f' w' g' d') <- (case slstmt of
Left s -> error s
Right e -> Right e);
nsl <- (checkListErr $ map convSI sl');
nf <- newFr f';
nw <- newWh w';
return $ Select nsl nf nw g' d'}
where slstmt = p c (Select sl f w g d)
它们的意思是这样的显式模式匹配:
applyCosPass :: CosCtx a => (a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
applyCosPass p c (UnionAll q1 q2) =
UnionAll <$> applyCosPass p c q1 <*> applyCosPass p c q2
applyCosPass p c (Select sl f w g d) = do
slstmt <- p c (Select sl f w g d)
case slstmt of
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'
... other cases -> error "Pattern match failed" -- Boooo
where ...
do 符号中 <-
箭头的左侧不应保留任何模式匹配。
请注意,您应该检查 Select ...
是否真的是这里唯一可能的情况,否则您可能应该处理其他情况。
我试图改编一个旧的 Haskell 项目,它现在与最新的 GHC 不兼容(MonadFail
现在是默认的)。
applyCosPass :: CosCtx a => (a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
applyCosPass p c (UnionAll q1 q2) =
UnionAll <$> applyCosPass p c q1 <*> applyCosPass p c q2
applyCosPass p c (Select sl f w g d) =
do (Select sl' f' w' g' d') <- p c (Select sl f w g d)
nsl <- (checkListErr $ map convSI sl')
nf <- newFr f'
nw <- newWh w'
return $ Select nsl nf nw g' d'
where ...
它returns错误如下:
• Could not deduce (MonadFail (Either String))
arising from a do statement
with the failable pattern ‘(Select sl' f' w' g' d')’
from the context: CosCtx a
bound by the type signature for:
applyCosPass :: forall a.
CosCtx a =>
(a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
at src/CosetteParser.lhs:(648,3)-(649,63)
• In a stmt of a 'do' block:
(Select sl' f' w' g' d') <- (case slstmt of
Left s -> error s
Right e -> Right e)
根据 Haskell Wiki 中的选项 2“Adapting New Code”,代码已修改为显式模式匹配,但错误仍然存在。这里可能缺少什么?
applyCosPass p c (Select sl f w g d) =
do {(Select sl' f' w' g' d') <- (case slstmt of
Left s -> error s
Right e -> Right e);
nsl <- (checkListErr $ map convSI sl');
nf <- newFr f';
nw <- newWh w';
return $ Select nsl nf nw g' d'}
where slstmt = p c (Select sl f w g d)
它们的意思是这样的显式模式匹配:
applyCosPass :: CosCtx a => (a -> QueryExpr -> Either String QueryExpr)
-> a -> QueryExpr -> Either String QueryExpr
applyCosPass p c (UnionAll q1 q2) =
UnionAll <$> applyCosPass p c q1 <*> applyCosPass p c q2
applyCosPass p c (Select sl f w g d) = do
slstmt <- p c (Select sl f w g d)
case slstmt of
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'
... other cases -> error "Pattern match failed" -- Boooo
where ...
do 符号中 <-
箭头的左侧不应保留任何模式匹配。
请注意,您应该检查 Select ...
是否真的是这里唯一可能的情况,否则您可能应该处理其他情况。