Haskell:使用列表理解对 Monad 进行排序

Haskell: Using list comprehension in sequencing a Monad

我正在阅读这篇关于 monadic parser in Haskell 的论文,作为新手,我无法理解以下结构:

newtype Parser a = Parser (String -> [(a, String)])

instance Monad Parser where
  return a = Parser (\cs -> [(a,cs)])
  p >>= f  = Parser (\cs -> concat [parse (f a) cs’ |
                               (a,cs’) <- parse p cs])

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

文中说:

Using a deconstructor function for parsers defined by parse (Parser p) = p, the parser p >>= f first applies the parser p to the argument string cs to give a list of results of the form (a,cs’), where a is a value and cs’ is a string. For each such pair, f a is a parser which is applied to the string cs’.

为什么 (f a) 而不是 f 是解析器?为什么需要传递 'a'?

(>>=) 的类型,使用 monad Parser 实例化,具有此类型签名:

(>>=) :: Parser a -> (a -> Parser b) -> Parser b

因此,当定义 p >>= f 时,p 的类型为 Parser a,而 f 的类型为 a -> Parser b。这就是 f a 是解析器而不是 f 的原因:f 是从 aParser b 的函数。

之所以这样,是因为没有它,我们可以组合解析器……但我们永远无法在下一个解析器中使用前一个解析器的结果!通过向前传递前一个解析器的结果,我们可以从多个解析器的结果中构建数据,例如:

parseTwoOf :: Parser a -> Parser (a, a)
parseTwoOf p = p >>= \first -> p >>= \second -> return (first, second)