我一直在寻找用Haskell编写一个词法分析器,并偶然发现了这些函数。
如果定义,
some
和many
应该是 方程:
some v = (:) <$> v <*> many v
many v = some v <|> pure []
我知道some
中的(:)
被提升并应用于v
的值,以便将其附加到many v
中返回的列表中。
但是为什么many
的定义以some
开头呢?为什么它会与pure []
连接?
这两个功能之间的关系或区别是什么?some
和many
是这些方程的最小解意味着什么?递归是如何停止的?帮助!
- >
some p
表示 p 的一个或多个匹配项 many p
表示 p 的零个或多个匹配
对于输入"abc"
,many letter
和some letter
都将解析abc
。
但是对于输入"123"
,many letter
会输出空字符串""
。some letter
将报告错误。
根据定义。some v
至少需要 1 个v
匹配,所以我们可以先解析v
然后我们需要 0 个或多个v
匹配,即many v
。它是这样的:
some v = do
first_match <- v
rest_matches <- many v
return $ first_match : rest_matches
这与some v = (:) <$> v <*> many v
相同。
但对于many v
.它将匹配some v
(1 或更多(或什么都不匹配(纯 [](。
many v = if matches (some v) then return (some v) else return nothing
.
您可以尝试从代码战争中从头开始编写应用程序解析器。
函数珍珠也是关于解析组合器的非常好的参考。
- https://www.codewars.com/kata/writing-applicative-parsers-from-scratch
- http://www.cs.nott.ac.uk/~pszgmh/pearl.pdf