2012-09-29 22 views
3

在第76页上,我们定义了一个函数item作为解析器 - 如果失败,则函数需要String并返回[(Char, String)][]Haskell编程中的函数解析器示例

第78页,我们定义一个函数sat,需要一个谓语p和“包装”解析器建设围绕

p :: (Char -> Bool) -> Parser Char 
sat p = do x <- item 
      if p x then return x else failure 

什么我不明白的是<-的魔力呢?如果item的结果不为空,那么这个运算符应该展开列表并从元组中取出第一项,否则它应该产生一些不会扼住谓词的东西。我错过了什么?

+0

看起来您正在使用Graham Hutton的书“Programming in Haskell”。格雷厄姆在本章中使用的并非严格Haskell的简化 - 请参阅本章(8.9节)的结束语以及Graham网页上关于可直接执行Haskell的在线代码。 –

回答

3
do x <- item 
    if p x then return x else failure 

这是语法糖

item >>= (\x -> if p x then return x else failure) 

>>=是一元绑定操作。

你缺少的是:Parser类型的>>=的定义是什么? (凡在本书是定义ParserMonad实例?它将开始instance Monad Parser where

1

do符号被脱到单子运营商(>>=)的应用。更确切地说,sat的定义解决了以下定义。

sat p :: (Char -> Bool) -> Parser Char 
sat p = 
    item >>= \x -> if p x then return x else failure 

操作(>>=)首先应用item解析器到输入端。正如你正确地看到这个解析器产生了第一个字符。然后,(>>=)将第一个解析器的结果传递给它的第二个参数,即函数\x -> if p x then return x else failure。该函数检查谓词是否满足输入流的第一个字符。如果满足,该函数将生成一个解析器(return x),该解析器不会消耗任何输入,并且只会产生x作为结果。如果它不满足谓词,则函数会生成解析器,该解析器对于任何输入都会失败(failure)。