【问题标题】:Haskell defined a simple parser to recognise symbols. failure in some testingHaskell 定义了一个简单的解析器来识别符号。某些测试失败
【发布时间】:2026-01-13 15:00:01
【问题描述】:

我目前正在阅读“在 48 小时内为自己编写一个方案”,在第 2 章中它定义了一个简单的解析器 'symbol' 来识别符号,然后定义一个函数 'readExpr' 来调用解析器。

module Main where

import System.Environment
import Text.ParserCombinators.Parsec hiding (spaces)

main :: IO ()
main = do args <- getArgs
          putStrLn (readExpr (args !! 0))

symbol :: Parser Char
symbol = oneOf "!$%&|*+-/:<=?>@^_~#"

readExpr :: String -> String
readExpr input = case parse symbol "lisp" input of
    Left err -> "Not Found" ++ show err
    Right val -> "Found value" ++ show val

但是当我尝试一些测试时:

>>> ghc -package parsec -o hii C1.hs

>>> ./hii *

上面写着:

Not Found"lisp" (line 1, column 1):
unexpected "A"

此外,一些其他符号(如 & 或 #)也不起作用,并给出“索引太大错误”。但符号如:%,@,!等这些工作正常。 我不明白为什么有些符号有效,而有些则无效。

此外,如果我在该符号上添加引号:

./hi "#"

Found value'#'

现在所有符号都可以工作了...

由于我真的不熟悉 monad 的东西,有人可以向我解释一下吗?

【问题讨论】:

    标签: parsing haskell monads


    【解决方案1】:

    * 扩展为当前工作目录中的所有文件。我猜如果你执行ls,第一个文件名是以A开头的。

    # 用于 cmets 开始,因此没有参数传递给 hii&amp; 将工作带入背景。

    quotes 会阻止 shell 翻译 *#!,所以尝试引用每个传递的 arg,就可以了。


    1. http://tldp.org/LDP/abs/html/special-chars.html

    【讨论】:

    • 在第一段中,最好指出扩展是由shell完成的,与Haskell完全无关。 Haskell 程序永远不会看到*,而只会看到它的扩展。使用echo commandWithFunnyChars 有时也有助于查看扩展。