简体   繁体   中英

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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