[英]Haskell GHCi - Using EOF character on stdin with getContents
[英]Why is gnuplot plot not receiving the entirety of stdin from getContents?
我有懶惰IO的問題,但我不知道如何解決它。
我這里有三個小測試程序,但V2是我真正想要的東西。
在某個地方,似乎要么提前停止getContents,要么gnuplot早早完成寫作。
問題的關鍵是“如何從stdin中獲取內容,並在此處使用gnuplot進行繪制”,但我也想知道如何調試底層問題。
版本1,沒有處理gnuplot。 使用paste <(seq 10000) <(seq 10000) | runhaskell /tmp/hasktest2.hs
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)])
這取決於你最終得到的種族條件,以及你是否得到了一個情節。
函數plotPathStyle
分支一個新的Haskell線程,其中調用了gnuplot
。 此線程使用您傳遞的列表,因此如果列表是通過惰性IO獲取的,則只有此線程才會實際讀取該文件。 plotPathStyle
函數或多或少地立即返回,在主線程結束時,程序將關閉。
因此,根據調度的發生方式,您可能會看到截斷輸出或根本沒有gnuplot窗口。 (如果我實際編譯程序而不是通過runhaskell
調用,我通常不會得到任何情節。)即使強制列表也不會使你免於這種情況。 如果你想要非交互式使用(例如,不是在GHCi中),似乎gnuplot
包推薦了Graphics.Gnuplot.Advanced
的接口,這為你提供了更多控制,例如允許你明確地等待繪圖完成。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.