Parsing 理解阿托帕塞克

Parsing 理解阿托帕塞克,parsing,haskell,attoparsec,Parsing,Haskell,Attoparsec,有人建议我使用ATOPASSEC解析文件,现在我必须了解如何使用它; 有人给了我这段代码: # type Environment=M.映射字符串 导入数据.Attoparsec(maybeResult) 将符合条件的Data.c.Char8作为 将限定数据.ByteString.Char8作为B导入 环境::A.解析器环境 环境=M.fromList A.sepBy条目A.endOfLine parseEnvironment=maybresult.flip A.feed B.empty。解析环境

有人建议我使用ATOPASSEC解析文件,现在我必须了解如何使用它; 有人给了我这段代码:

#
type Environment=M.映射字符串
导入数据.Attoparsec(maybeResult)
将符合条件的Data.c.Char8作为
将限定数据.ByteString.Char8作为B导入
环境::A.解析器环境
环境=M.fromList A.sepBy条目A.endOfLine
parseEnvironment=maybresult.flip A.feed B.empty。解析环境
空格=A.many$A.char“”
条目=(,)upTo':“upTo';”
upTo delimiter=B.unpack A.takeWhile(A.notInClass$delimiter:)
>A.char分隔符>>空格)
这很有效,但我不知道为什么: 使用flip的原因是什么?将A.feed的参数置于不同的顺序不是更容易吗?为什么B是空的? 有什么我可以学习的教程吗?
提前感谢

在对的回答中有一个关于需要
feed
的解释。正如布莱恩·奥沙利文(Atoparsec的创始人)所说:

如果您编写一个attoparsec解析器 消耗尽可能多的输入 在失败之前,你必须告诉老师 当 您已到达输入的末尾

您可以通过向它提供一个空的bytestring来实现这一点

我承认我编写了有问题的代码,在本例中我实际上没有使用
pointfree
。在这里,简单的组合对我来说很有意义:您运行解析器(
A.parse environment
),告诉它您完成了(
flip A.feed B.empty
),然后将其转换为
maybeResult
,作为一种基本的错误处理(
maybeResult
)。在我看来,这比尖锐的版本更清晰:

parseEnvironment b = maybeResult $ A.feed (A.parse environment b) B.empty

其余的我认为是相当惯用的,尽管我不确定为什么我会使用
>
而不是
*>

也许作者使用了
无点
parseEnvironment b = maybeResult $ A.feed (A.parse environment b) B.empty