Haskell Text.Parsec.Combinator选择不回溯

sin*_*nan 9 haskell parsec

我正在尝试用parsec解析一些Text:

data Cmd = LoginCmd String
         | JoinCmd String
         | LeaveCmd String
    deriving (Show)

singleparam :: Parser Cmd
singleparam = do
    cmd <- choice [string "leave", string "login", string "join"]
    spaces
    nick <- many1 anyChar
    eof
    return $ LoginCmd nick
Run Code Online (Sandbox Code Playgroud)

我希望choice尝试匹配"离开",如果失败,则尝试"登录"等.但它只会尝试匹配"离开",如果失败,则会出错.

ghci> parseTest singleparam (pack "login asdf")
parse error at (line 1, column 1):
unexpected "o"
expecting "leave"
ghci> parseTest singleparam (pack "leave asdf")
LoginCmd "asdf"
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Chr*_*icz 14

Parsec不会像这样自动回溯(为了提高效率).规则是,一旦分支接受令牌,则修剪备用分支.解决的方法是使用添加一个明确的回溯try (string "leave")try (string "login")等.

在您的示例中,'l'字符是将Parsec提交到第一个"leave"分支并放弃"login"和"join"的下一个分支的标记.

关于parsec的 Real World Haskell(书,在线)中的更多细节.