我写了一个Conduit
来生成一个项目流。这些项目具有自定义类型(例如Record
),每个项目都包含一些结构化数据。我正在尝试编写一个解析Conduit
- 流的下游Record
。
有趣的是,我发现parsec包中的许多概念在我的应用程序中都有意义。例如,我有时期望many
记录satisfy
特定谓词连续出现,或者我希望特定记录的一个实例恰好在另一个特定记录之后。所以我正在寻找重新实现Conduit
s的函数的方法,例如,
satisfy :: Monad m => (r -> Bool) -> ConduitM r a m rp
many :: Monad m => ConduitM r a m rp -> ConduitM r a m [rp]
sepBy :: Monad m => ConduitM r a m rp -> ConduitM r a m sep -> ConduitM r a m [rp]
在上面的例子中专门针对这些
satisfy :: (Record -> Bool) -> ConduitM Record () IO Record
many :: ConduitM Record () IO Record -> ConduitM Record () IO [Record]
sepBy :: ConduitM Record () IO Record -> ConduitM Record () IO Record -> ConduitM Record a IO [Record]
这样我就可以编写像:
这样的简洁代码parserC :: Sink Record IO (Record, [Record], [Record])
parserC = do
red <- satisfy isRecordRed
blues <- many $ satisfy isRecordBlue
assorted <- anyRecord `sepBy` satisfy isRecordPurple
return (red, blues, assorted)
现在看一下parsec的文档,我发现这些函数实际上是为非常通用的Stream
类定义的。所以我认为应该可以挂钩包装。但是,我遇到的一个难点是parse
函数可以处理整个流s
。有没有办法以流线方式解析parsecT
?