I'm having an issue with lazy IO, but I don't know how to fix it.
I've got three small test programs here, but with V2 being the thing I actually want.
Somewhere, it seems that either getContents is being halted early, or gnuplot is finishing writing early.
The crux of the question is 'how can I take stuff from stdin, and plot it with gnuplot here', but I'd also like to know how to debug the underlying problem.
Version 1, no dealing with gnuplot. Run with paste <(seq 10000) <(seq 10000) | runhaskell /tmp/hasktest2.hs
, prints out (10000.0,10000.0)
as expected. Clearly all of stdin is loaded.
import Data.List
main = do
contents <- getContents
print . last . map f . lines $ contents
f :: String -> (Double, Double)
f s = (read x, read y)
where
[x,y] = words s
V2: Attempting to plot whatever comes from stdin. This is run the same way as V1 - the temporary file that gnuplot makes gets truncated, so I don't get a plot. However, if I run with with 1000 instead of 10k, it does work - it gets truncated at some point when writing the gnuplot csv file, so I have a line that looks like 1767.0, 1767
with no \n
.
main = do
contents <- getContents
plotPathStyle [] (PlotStyle Points (DefaultStyle (1))) . map f . lines $ contents
f :: String -> (Double, Double)
f s = (read x, read y)
where
[x,y] = words s
V3: Just to test that gnuplot can actually deal with 10k points, and write them to a file - this produces a plot, as expected.
import Graphics.Gnuplot.Simple
main = plotPathStyle [] (PlotStyle Points (DefaultStyle (1))) (zip [1..10000] [1..10000] :: [(Double, Double)])