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

Haskell自定义Parser类型检查子串报错:模式匹配解析错误排查

问题分析与解决

你的代码存在几个关键问题,导致语法和逻辑错误:

1. Case语句的语法错误

Haskell的case表达式分支是模式匹配,不能直接写条件判断表达式(比如(isInfixOf "true", s) == True)。正确的做法是使用guard(|)或直接用条件表达式处理逻辑。

2. 类型不匹配问题

你导入了Data.Text的函数,但Parser的输入是String类型,而Data.Text.isInfixOf和replace的参数是Text类型,直接混用会导致类型错误。如果要使用String,应该用Data.List中的字符串操作函数。

3. 逻辑不符合需求

你的需求是:只有当字符串以"true"或"false"开头时才匹配(比如"ttruehello"包含"true"但不是前缀,所以返回Nothing),但你用了isInfixOf(检查任意子串存在),这和需求矛盾。同时,匹配到"false"时应该返回False,而不是True。


修正后的代码

import Data.List (isPrefixOf)

newtype Parser a = Parser (String -> Maybe (String, a))

parseBool :: Parser Bool
parseBool = Parser (\s ->
  if "true" `isPrefixOf` s
    then Just (drop 4 s, True)
    else if "false" `isPrefixOf` s
           then Just (drop 5 s, False)
           else Nothing)

代码解释

  • 使用Data.List.isPrefixOf检查字符串是否以目标前缀开头,完全符合需求中的匹配规则。
  • 用drop函数去掉匹配的前缀部分:"true"长度为4,所以drop 4;"false"长度为5,所以drop 5。
  • 逻辑清晰:先检查"true"前缀,再检查"false"前缀,都不匹配则返回Nothing。
  • 避免了类型不匹配问题,直接使用String类型的操作函数。

测试验证

  • 输入"truehello":返回Just ("hello", True),符合需求。
  • 输入"ttruehello":因为不是以"true"开头,返回Nothing,符合需求。
  • 输入"falseworld":返回Just ("world", False),正确处理false分支。

内容的提问来源于stack exchange,提问作者Mon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:36:05