简体   繁体   English

Haskell解析器组合器-字符串函数

[英]Haskell Parser Combinators - String function

I have been reading a tutorial about parser combinators and I came across a function which I would like a bit of help in trying to understand. 我一直在阅读有关解析器组合器的教程,并且遇到了一个函数,在理解该函数时我需要一点帮助。

satisfy :: (Char -> Bool) -> Parser Char
satisfy p = item `bind` \c ->
  if p c
  then unit c
  else (Parser (\cs -> []))

char :: Char -> Parser Char
char c = satisfy (c ==)

natural :: Parser Integer
natural = read <$> some (satisfy isDigit)

string :: String -> Parser String
string [] = return []
string (c:cs) = do { char c; string cs; return (c:cs)}

My question is how does the string function work or rather how does it terminate, say i did something like: 我的问题是字符串函数如何工作,或者它如何终止,说我做了类似的事情:

let while_parser = string "while"

and then i used it to parse a string say for example parse while_parser "while if" , it will correctly parse me the "while". 然后我用它来解析一个字符串,例如parse while_parser "while if" ,它将正确地解析我“ while”。

however if i try something like parse while_parser "test it will return []. 但是,如果我尝试parse while_parser "test类的东西,它将返回[]。

My question is how does it fail? 我的问题是它怎么会失败? what happens when char c returns an empty list? 当char c返回一个空列表时会发生什么?

Let's say your Parser is defined like this: 假设您的Parser是这样定义的:

newtype Parser a = Parser { runParser :: String -> [(a,String)] }

Then your Monad instance would be defined something like this: 然后,您的Monad实例将定义如下:

instance Monad Parser where
  return x = Parser $ \input -> [(x, input)]
  p >>= f = Parser $ \input -> concatMap (\(x,s) -> runParser (f x) s) (runParser p input)

You're wondering what happens when char c fails in this line of code: 您想知道当char c在此代码行中失败时会发生什么:

string (c:cs) = do { char c; string cs; return (c:cs) }

First, let's desugar it: 首先,让我们将其脱糖:

string (c:cs) = char c >>= \_ -> string cs >>= \_ -> return (c:cs)

Now the part of interest is char c >>= \\_ -> string cs . 现在感兴趣的部分是char c >>= \\_ -> string cs From the definition of char and subsequently the definition of satisfy we see that ultimately runParser (char c) input will evaluate to [] when char c fails. 从定义char和随后的定义satisfy我们看到,最终runParser (char c) input将计算为[]char c失败。 Look at the definition of >>= when p is char c . pchar c时,查看>>=的定义。 concatMap won't have any work to do because the list will be empty! concatMap将不做任何工作,因为列表将为空! Thus any calls to >>= from then on will just encounter an empty list and pass it along. 因此,从此以后对>>=任何调用都只会遇到一个空列表并将其传递。

One of the wonderful things about referential transparency is that you can write down your expression and evaluate it by substituting definitions and doing the function applications by hand. 关于引用透明性的妙处之一是您可以写下表达式并通过替换定义并手动执行函数应用来对其进行求值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM