Haskell如何让函数返回不同类型:支持返回运算符或字符串错误提示
问题核心错误原因
你的写法存在2个核心问题:
- 类型定义逻辑颠倒:
Either (Parser (Double -> Double -> Double)) (Parser String)的语义是「整个值要么是返回运算符的解析器,要么是返回错误的解析器」,和你的需求不符。你需要的是「单个解析器,执行后返回的结果要么是运算符、要么是错误字符串」,应该把Either放在Parser的泛型参数内部。 - 语法优先级错误:
return Left (**)没有正确处理函数优先级,需要用$或者括号包裹Left的参数。
正确实现方案
方案1:自定义返回Either的实现(适合需要自行处理错误分支的场景)
-- 解析结果语义:Left 为正常匹配的运算符,Right 为错误提示 mulop :: Parser (Either (Double -> Double -> Double) String) mulop = do symbol "^" return $ Left (**) +++ do symbol "*" return $ Left (*) +++ do symbol "/" return $ Left (/) +++ pure $ Right "无效的乘法类运算符,仅支持^、*、/"
注意:因为mulop返回类型变更,原有的
chainl1调用需要同步调整,增加对Either分支的判断处理。
方案2:使用解析库自带错误能力(更简洁,兼容原有调用)
如果你用的是Parsec等标准解析库,可以直接用库内置的错误标注能力,不需要额外套Either,完全兼容原有chainl1调用:
import Text.Parsec ((<?>)) mulop :: Parser (Double -> Double -> Double) mulop = do symbol "^" return (**) +++ do symbol "*" return (*) +++ do symbol "/" return (/) <?> "乘法类运算符(^、*、/)"
解析失败时会自动返回你定义的错误提示,不需要手动处理分支。
内容的提问来源于stack exchange,提问作者Chadley Maggott
相关产品推荐
相关产品推荐

