You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell如何让函数返回不同类型:支持返回运算符或字符串错误提示

问题核心错误原因

你的写法存在2个核心问题:

  1. 类型定义逻辑颠倒:Either (Parser (Double -> Double -> Double)) (Parser String)的语义是「整个值要么是返回运算符的解析器,要么是返回错误的解析器」,和你的需求不符。你需要的是「单个解析器,执行后返回的结果要么是运算符、要么是错误字符串」,应该把Either放在Parser的泛型参数内部。
  2. 语法优先级错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 02:27:03