为什么gnuplot绘图没有从getContents接收整个stdin?

时间:2015-03-04 11:08:12

标签: haskell lazy-io

我遇到懒惰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)])

1 个答案:

答案 0 :(得分:3)

这取决于你最终得到的种族条件,以及你是否得到了一个情节。

函数plotPathStyle分叉调用gnuplot的新Haskell线程。此线程使用您传递的列表,因此如果列表是通过惰性IO获取的,则只有此线程才会实际读取该文件。函数plotPathStyle或多或少立即返回,在主线程结束时,程序将关闭。

因此,根据调度的发生方式,您可能会看到截断输出或根本没有gnuplot窗口。 (如果我实际编译程序而不是通过runhaskell调用,我通常不会得到任何情节。)即使强制列表也不会使你免于这种情况。如果您想要非交互式使用(即,不是来自GHCi内),gnuplot软件包似乎推荐Graphics.Gnuplot.Advanced中的界面,这可以让您获得更多控制权,例如允许您明确等待绘图完成。

相关问题