Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I output values from a list as they are calculated?

Tags:

haskell

frp

I have a long-running computation that outputs a list. I want to output values from this list as they are computed. What would be a neat way to do this?

Currently I use mapM_ print to print each value to STDOUT. This works well enough for the simple case of printing values to the command line, but feels a little bit hacky and hard to work with.

Additionally, at some point, I want to turn my command-line output into an interactive visualization. How could I go about turning my list into something like a stream of events from FRP? Being able to plug this into an existing GUI framework as a source of events would be great.

Rewriting the function to use something other than a list is an option, although a solution that allows me to take the list as-is would be ideal.

like image 947
Tikhon Jelvis Avatar asked Jan 06 '13 11:01

Tikhon Jelvis


1 Answers

This is a job for iteratees and iteratees like libraries.

Using the Proxy library.

import Control.Proxy

runProxy $ fromListS [1..10] >-> <processing> >-> printD >-> <more> processing>

Where <processing> is the addition calculations you need to make.

Similar questions: lazy version of mapM, Is Haskell's mapM not lazy?

For example:

> labeledPrint label x = putStrLn $ label ++ show x
> runProxy $ fromListS [1..4] >-> printD >-> mapD (*2) 
                              >-> useD (labeledPrint "Second printer: ")
1
Second printer: 2
2
Second printer: 4
3
Second printer: 6
4
Second printer: 8

If you reverse the order of application and use <-< instead of >-> then it looks like normal function application.

runProxy $ useD (labeledPrint "Second printer: ") <-< mapD (*2)
                                                  <-< printD
                                                  <-< fromListS [1..4]
like image 181
Davorak Avatar answered Sep 28 '22 16:09

Davorak