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

使用Haskell与Parsec解析|分隔的两个数字列表遇阻求助

Parsec解析问题修复与入门教程推荐

问题修复:数字列表解析错误

你的代码中firstList解析失败的核心原因是空格处理不匹配输入格式:

  • 原代码用many1 (many1 Parsec.digit <* Parsec.space),强制要求每个数字后必须跟空格,但输入中|前的最后一个数字后是空格+|,而你用Parsec.char '|'直接匹配时,没有处理|前的空格,导致解析器在匹配完最后一个数字的空格后,遇到的是空格而非|,触发失败。
  • 更合适的做法是用sepBy1组合子处理数字列表(它专门用于解析分隔符分隔的元素),同时处理|前后的空格。

修正后的代码如下:

import Text.Parsec
import Text.Parsec.String (Parser)

data Data = Data Int [Int] [Int]
    deriving Show

toInt :: String -> Int
toInt = read

parseRow :: Parser Data
parseRow = do
    _ <- string "Data"
    spaces
    cid <- toInt <$> many1 digit
    _ <- string ": "
    firstList <- map toInt <$> sepBy1 (many1 digit) spaces
    spaces  -- 跳过|前的空格
    _ <- char '|'
    spaces  -- 跳过|后的空格
    secondList <- map toInt <$> sepBy1 (many1 digit) spaces
    return $ Data cid firstList secondList

关键调整点:

  1. 用sepBy1 (many1 digit) spaces替代手动的many1组合,自动处理数字间的任意空格分隔(包括多个空格)。
  2. 在匹配|前后显式调用spaces,跳过所有空白字符,兼容输入中|前后的空格变化。
  3. 可以用parseTest parseRow "Data 1: 43 76 123 98 32 | 32 88 43 123 43"测试解析效果。

新手友好的Parsec入门资源

  1. 《Real World Haskell》Parsec章节:这本书的Parsec部分从基础组合子讲起,用实际例子(比如解析配置文件、表达式)逐步讲解,适合新手建立核心概念,重点理解do notation在解析中的使用,以及string、spaces、sepBy、between等常用组合子的作用。
  2. Parsec官方文档入门示例:官方文档里的入门部分有简单的解析案例,比如解析CSV、简单表达式,能帮你快速掌握基本用法,同时学会如何调试解析错误(比如用parseTest查看失败原因)。
  3. Haskell社区入门教程:很多Haskell博客会有Parsec入门系列,比如从解析简单数字列表开始,逐步扩展到复杂数据结构,重点讲解如何组合小解析器构建大解析器,以及错误处理的基础技巧。

内容的提问来源于stack exchange,提问作者LA.27

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 23:07:17