秒差距的条件

Conditions in Parsec

如果我有一个解析器而不是将一串由 space 分隔的数字读取到一个整数列表中,我该如何处理尾随的 space?目前我有:

row :: Parser [Int]
row  = do
  optional spaces
  f <- (many (oneOf "0123456789"))
  r <- ((char ' ') >> row) <|> pure []
  pure (read f:r)

对于没有尾随 space 但尾随 space.

的字符串可以正常工作
>λ= parse row "" " 2  0 12  3     7"
Right [2,0,12,3,7]

>λ= parse row "" " 2  0 12  3     7  "
Right [2,0,12,3,7,*** Exception: Prelude.read: no parse

这个问题的解决方案是什么,更重要的是,如果 '\n' 被消耗,那么解析器 returns []

编辑: 通过阅读@amalloy 的回答和 parsec 源代码,我认为添加一个适用于此处的版本很有用(尽管,@amalloy 不尝试和滚动现有功能的建议更有意义)

row :: Parser [Int]
row = do
  spaces
  f <- (read <$> many1 digit)
  do
    many1 $ char ' '
    r <- row
    pure (f:r) <|> pure [x]
  <|> pure []

与其自己实现所有这些低级的东西,我建议只使用 sepEndBy。例如,

row :: Parser [Int]
row = spaces *> (int `sepEndBy` many1 space)
  where int = read <$> many1 digit