我遇到懒惰IO的问题,但我不知道如何修复它。
我在这里有三个小测试程序,但V2是我真正想要的东西
在某个地方,似乎要么提前停止getContents,要么gnuplot早早完成写作。
问题的症结在于如何从标准输入中获取内容,并在此处使用gnuplot进行绘制,但我也想知道如何调试底层问题。
版本1,没有处理gnuplot。使用paste <(seq 10000) <(seq 10000) | runhaskell /tmp/hasktest2.hs
运行,按预期打印出(10000.0,10000.0)
。显然所有stdin都已加载。
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:尝试绘制来自stdin的任何内容。这与V1的运行方式相同 - gnuplot的临时文件被截断,所以我没有得到一个情节。但是,如果我使用1000而不是10k运行,它确实有效 - 在编写gnuplot csv文件时会在某些时候被截断,所以我有一行看起来像1767.0, 1767
而没有\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:只是为了测试gnuplot实际上可以处理10k点,并将它们写入文件 - 这会产生一个情节,如预期的那样。
import Graphics.Gnuplot.Simple
main = plotPathStyle [] (PlotStyle Points (DefaultStyle (1))) (zip [1..10000] [1..10000] :: [(Double, Double)])
答案 0 :(得分:3)
这取决于你最终得到的种族条件,以及你是否得到了一个情节。
函数plotPathStyle
分叉调用gnuplot
的新Haskell线程。此线程使用您传递的列表,因此如果列表是通过惰性IO获取的,则只有此线程才会实际读取该文件。函数plotPathStyle
或多或少立即返回,在主线程结束时,程序将关闭。
因此,根据调度的发生方式,您可能会看到截断输出或根本没有gnuplot窗口。 (如果我实际编译程序而不是通过runhaskell
调用,我通常不会得到任何情节。)即使强制列表也不会使你免于这种情况。如果您想要非交互式使用(即,不是来自GHCi内),gnuplot
软件包似乎推荐Graphics.Gnuplot.Advanced
中的界面,这可以让您获得更多控制权,例如允许您明确等待绘图完成。