[Haskell-cafe] Resumable applicative parsing from tail end?

Ruben Astudillo ruben.astud at gmail.com
Thu Jul 7 03:53:40 UTC 2016


On 20/06/16 06:42, martin wrote:
> as the simulation progresses, I collect "primary" log entries, each one associated with a timestamp. These entries carry
> the information I am interested in (and not so much the final state). Currently I am using a simple list to collect log
> entries. Since (:) is so much easier than (++) I prepend new entries to the head of the list. So my log runs backwards
> in time with the oldest entries at the tail end.
>
> Because the log-entries are typically too fine-grained to be useful, I want to aggregate several of them into a single
> log entry in a secondary log. I want to do this "as I go" and discard primary log entries which are already aggregated.
> Thus I can keep the primary log reasonably small.
>
> I thought that aggregation is just a special case of parsing. And indeed, I could write an applicative  parser
>
> PrimaryLog -> (PrimaryLog, SecondaryLog)
>
> which does the trick, except I had to reverse the ordering of the primary log. This is because the parser/aggregator
> must parse from past to future, because there may be new log entries coming up in the future. I need to be able to
> resume parsing where I left off whenever new primary log entries are entered, becuase I may then have just enough
> unconsumed primary log entries to create another secondary entry.

You are dealing with the classic "streaming problem" when you keep a
growing "Log" that you can't reduce until the end of the process; 
instead of it being returned incrementally as when you `map a list`.

Luckily this problem has two standards solution namely pipes/conduit. 
They let you recover the streaming behaviour you want and will make your 
parsing go left-to-right.

--
-- Ruben Astudillo


More information about the Haskell-Cafe mailing list