许多人在哪里产生空字符串?

时间:2014-11-15 14:13:59

标签: regex parsing haskell

我目前正在阅读Graham Hutton撰写的Haskell编程。我被困在Parsers的章节上。其中有两个相互递归的函数定义为:

many  p = many1 p +++ return []
many1 p = do v  <- p
             vs <- many p   
             return (v:vs)

many实际上转化为这种形式:

many1 p = p >>= (\ v -> many p >>= (\ vs -> return (v : vs)))

>>=运算符定义为:

p >>= f =  P (\inp -> case parse p inp of
                           []        -> []
                           [(v,out)] -> parse (f v) out)

+++运算符定义为:

p +++ q =  P (\inp -> case parse p inp of
                           []        -> parse q inp
                           [(v,out)] -> [(v,out)])

与此问题相关的其他功能如下:

parse             :: Parser a -> String -> [(a,String)]
parse (P p) inp   =  p inp

sat p =  do x <- item
            if p x then return x else failure

digit =  sat isDigit

failure = P (\inp -> [])
item    = P (\inp -> case inp of
                          []     -> []
                          (x:xs) -> [(x,xs)])
return v = P (\inp -> [(v,inp)])

现在,当尝试使用many1来解析字符串"a"中的数字时,例如:

parse (many digit) "a"

结果为[("","a")]

尝试使用"a"解析字符串many1中的数字时:

parse (many1 digit) "a"

结果为[]

我想我理解为什么第二个结果。 (many1 digit)尝试解析字符串"a",因此调用digit "a"失败,因为"a"不是数字,因此返回空列表[]

但是,我不理解使用(many digit)时的第一个结果。如果(many1 digit)返回[],那么显然它会失败,因此在+++运算符中,会执行第二个case表达式。但是,当我尝试parse (return []) "a"时,我得到的结果是[([], "a")]

many的结果为[("", "a")]时,我无法理解many1的结果为[]的原因。 任何帮助表示赞赏。

P.S。我已经看过this question,但它并没有给我我想要的答案。

1 个答案:

答案 0 :(得分:3)

如果您感到困惑,那么您在预期[("", "a")]时会回到[([], "a")]

字符串是Chars列表。所以""是一个空的Chars列表。由于[]是任何类型的空列表,因此""只是[]的特例。换句话说,[] :: [Char]完全等同于""

因此,由于您的解析器需要生成一个字符串,因此已知空列表的类型为[Char],因此打印为""而不是[]