简体   繁体   English

Haskell:FRP 反应性 Parsec?

[英]Haskell: FRP Reactive Parsec?

Is there (or is it possible to have) a reactive Parsec (or any other pure functional parser) in Haskell? Haskell 中是否有(或可能有)反应式Parsec (或任何其他纯功能解析器)?

Simply put, I want to feed parser myself char by char and get results as much as I feed enough to get output.简而言之,我想逐个字符地为解析器提供数据,并获得足够多的结果以获取 output。

Or much simpler, how can I do it in foldr or at least map ?或者更简单,我怎样才能在foldr或至少map中做到这一点?

Do we need a different version of them to support such reactive behavior?我们是否需要它们的不同版本来支持这种反应行为?

EDIT编辑

My question is about FRP in particular.我的问题特别是关于 FRP。 I used a parser as an example, which was the best I could think of to clarify my question and give big picture of what I need.我以解析器为例,这是我能想到的最好的方法来澄清我的问题并全面了解我的需求。

I believe FRP is not just about UI, right?我相信 FRP 不仅仅是关于 UI,对吧?

You cannot do online parsing in Parsec, it has to consume all the input in order to determine whether there is a valid parse or not.您不能在 Parsec 中进行在线解析,它必须消耗所有输入才能确定是否存在有效解析。

However there are alternatives.然而,还有其他选择。 One possiblity is to use the Utrecht parser combinators , it has online parsing among its features.一种可能是使用Utrecht 解析器组合器,它具有在线解析功能。

I don't think it's right to call this "FRP", the right name for this kind of thing is online algorithm , which means that the parser produces output as soon as it receives input.我不认为把这个叫做“FRP”是正确的,这种东西的正确名称是online algorithm ,这意味着解析器一收到输入就会产生 output 。 (As opposed to offline algorithm , where the parser receives the entire input upfront and produces an output from that.) (与离线算法相反,解析器预先接收整个输入并从中生成 output。)

In Haskell, lazy evaluation makes it easy to write online algorithms.在 Haskell 中,惰性求值使得编写在线算法变得容易。 Malcom Wallace has developed a special set of parser combinators for online parsing that use lazy evaluation. Malcom Wallace 开发了一组特殊的解析器组合器,用于使用惰性求值的在线解析。

You can do online parsing in Parsec, but to do so you need to layer it on top of something like an iteratee.您可以在 Parsec 中进行在线解析,但要做到这一点,您需要将它放在类似 iteratee 的东西之上。

Parsec 3 is capable of working with arbitrary Stream types, so you can make an instance of Stream which views the current 'stream' as a position, and uses an iteratee to retrieve the value at that position. Parsec 3 is capable of working with arbitrary Stream types, so you can make an instance of Stream which views the current 'stream' as a position, and uses an iteratee to retrieve the value at that position.

One such example is the iteratee-parsec package .一个这样的例子是iteratee-parsec package

Another approach is provided by parsing trifecta talk on iteratees and parsec (warning PDF):通过解析关于 iteratees 和 parsec 的 trifecta talk提供了另一种方法(警告 PDF):

A compromise is to build an iteratee-like type that buffers the last few chunk fragments rather than all of them to enable it to retain bounded space utilization, and rely on the iteratee machinery for backtracking beyond that.一种折衷方案是构建一个类似迭代器的类型,它缓冲最后几个块片段而不是所有块片段,以使其能够保持有限的空间利用率,并依赖迭代器机制进行回溯。 This is what I currently use, but I don't have any code online for it.这是我目前使用的,但我没有任何在线代码。

Once you have inverted control by running Parsec on top of an Iteratee, it is quite easy to feed it input a character at a time and see if it has managed to recognize anything yet.一旦你通过在 Iteratee 上运行 Parsec 来反转控制,就很容易一次输入一个字符,看看它是否已经设法识别任何东西。

Have a look at attoparsec-conduit, with the correct parser it can be a useful way to translate a stream of bytes into a stream of parsed data structures看看 attoparsec-conduit,使用正确的解析器,它可能是将 stream 字节转换为 stream 解析数据结构的有用方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM