我正在尝试通过Haskell编写一个简单的解析器,但卡在了一个无限循环中。
代码如下:
import Control.Applicative (Alternative, empty, many, (<|>))
data Parser a = Parser {runParser :: String -> [(a, String)]}
instance Functor Parser where
fmap f (Parser p) = Parser $ \s -> [(f x', s') | (x', s') <- p s]
instance Applicative Parser where
pure x = Parser $ \s -> [(x, s)]
(Parser pf) <*> (Parser p) = Parser $ \s -> [(f' x, ss') | (f', ss) <- pf s, (x, ss') <- p ss]
instance Alternative Parser where
empty = Parser $ \s -> []
(Parser p1) <|> (Parser p2) = Parser $ \s ->
case p1 s of
[] -> p2 s
xs -> xs
singleSpaceParser :: Parser Char
singleSpaceParser = Parser $ \s ->
( case s of
x : xs -> if x == ' ' then [(' ', xs)] else []
[] -> []
)
multiSpaceParser :: Parser [Char]
multiSpaceParser = many singleSpaceParser
我只需在ghci中加载此文件并运行:
runParser multiSpaceParser " 123"
我期望它会得到 [(" ", "123")]
,但实际上它陷入了一个无限循环。
我使用跟踪来调试,似乎 many
的值不正确。
我该如何修复这个 bug?
many
处理Alternative
,这意味着它将首先尝试singleSpaceParser
,如果失败了,它会尝试另一个singleSpaceParser
等。 - Willem Van Onsemdata
替换为newtype
,它应该可以工作。 - kosmikus