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

时间:2015-09-07 20:43:19

标签: haskell monads

我正在阅读关于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

它在文中说:

  

对解析器(Parser p)= p定义的解析器使用解构函数,解析器p&gt;&gt; = f首先将解析器p应用于参数字符串cs以给出表单结果列表(a, cs'),其中a是值,cs'是字符串。对于每个这样的对,f a是应用于字符串cs'的解析器。

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

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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