开发者

Haskell: FRP Reactive Parsec?

Is there (or is it possible to have开发者_运维问答) a reactive Parsec (or any other pure functional parser) in Haskell?

Simply put, I want to feed parser myself char by char and get results as much as I feed enough to get output.

Or much simpler, how can I do it in foldr or at least map?

Do we need a different version of them to support such reactive behavior?

EDIT

My question is about FRP in particular. 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?


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.

However there are alternatives. One possiblity is to use the Utrecht parser combinators, it has online parsing among its features.


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. (As opposed to offline algorithm, where the parser receives the entire input upfront and produces an output from that.)

In Haskell, lazy evaluation makes it easy to write online algorithms. Malcom Wallace has developed a special set of parser combinators for online parsing that use lazy evaluation.

  • Polyparse - library on hackage.
  • Partial parsing: combining choice with commitment - design article.


You can do online parsing in Parsec, but to do so you need to layer it on top of something like an 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.

One such example is the iteratee-parsec package.

Another approach is provided by parsing trifecta talk on iteratees and parsec (warning 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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜