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
是从 a
到 Parser b
的函数。
之所以这样,是因为没有它,我们可以组合解析器……但我们永远无法在下一个解析器中使用前一个解析器的结果!通过向前传递前一个解析器的结果,我们可以从多个解析器的结果中构建数据,例如:
parseTwoOf :: Parser a -> Parser (a, a)
parseTwoOf p = p >>= \first -> p >>= \second -> return (first, second)
我正在阅读这篇关于 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
是从 a
到 Parser b
的函数。
之所以这样,是因为没有它,我们可以组合解析器……但我们永远无法在下一个解析器中使用前一个解析器的结果!通过向前传递前一个解析器的结果,我们可以从多个解析器的结果中构建数据,例如:
parseTwoOf :: Parser a -> Parser (a, a)
parseTwoOf p = p >>= \first -> p >>= \second -> return (first, second)