3

在第 76 页,我们将一个函数定义item为解析器——一个接受 aString并返回[(Char, String)][]失败的函数。

在第 78 页,我们定义了一个函数sat,它接受一个谓词p并围绕它“包装”一个解析器结构

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

我不明白的是魔法<-?如果 的结果item不为空,则此运算符应该解开列表并从元组中获取第一项,否则它应该产生不会阻塞谓词的东西。我错过了什么?

4

2 回答 2

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

这是语法糖

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

>>=是一元绑定运算符。

您缺少的是:类型的定义是>>=什么Parser?(书中定义的Monad实例在哪里Parser?它将开始instance Monad Parser where。)

于 2012-09-29T13:23:11.877 回答
1

do表示法对 monad 运算符的应用程序没有糖分(>>=)。更准确地说, 的定义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) 都会失败。

于 2012-09-29T13:26:11.563 回答