處理用戶輸入無限,我想我的命令行的Haskell程序的功能是這樣的: 程序等待用戶輸入,如何閱讀和哈斯克爾
- 用戶類型的東西,按「輸入」
- 哈斯克爾處理輸入,示出了在stdout
- Haskell中等待下一個用戶輸入
- 結果如果沒有更多的輸入,用戶按Ctrl +終止程序d
我試過getContents。但getContents等待用戶在處理它們之前輸入所有行。
處理用戶輸入無限,我想我的命令行的Haskell程序的功能是這樣的: 程序等待用戶輸入,如何閱讀和哈斯克爾
我試過getContents。但getContents等待用戶在處理它們之前輸入所有行。
這裏有很多混淆。讓我們試着清理一下。
我試過getContents。但getContents等待用戶在處理它們之前輸入所有行。
這裏最有可能的是你編譯你的程序,並沒有注意到輸出的默認緩衝是塊緩衝。這是很容易解決:
f line = putStrLn ("Hi, " ++ line ++ "!")
main = do
hSetBuffering stdout LineBuffering -- or use NoBuffering
putStrLn "Enter some names."
input <- getContents
mapM_ f (lines input)
您應該使用NoBuffering
,如果你不上打印用戶輸入的每一行後一整行(包括換行符)計劃。
想要得到更準確的答案,我們需要看看您嘗試過的代碼無效。
問:但在第一次嘗試時,我使用「交互式顯示」,它不起作用。你知道爲什麼嗎?
答:因爲顯示將不會返回任何輸出,直到其整個輸入已耗盡。
這個答案不太正確。真正的答案是show
產生一個沒有換行的字符串! (雖然字符序列['\\','\n']
確實有時顯示,如果輸入是超過一行長。)因此,對於interact show
,您確實必須在stdout
上使用NoBuffering
。例如,如果你使用這個:
main = do
hSetBuffering stdout NoBuffering
interact show
...程序將在每行之後輸出更多的輸出。您可能還想將stdin
的緩衝設置爲NoBuffering
(而不是默認的LineBuffering
),因爲show
具有足夠的生產能力,因此每次擊鍵後都能產生更多的輸出。
這可以避免使用interact
時發生的懶惰I/O問題。
(如果我們不使用isEOF
,異常會,當我們按下Ctrl + d拋出。)
import Control.Monad (unless)
import System.IO (isEOF)
processEachLine :: (String -> IO a) -> IO()
processEachLine k = do
finished <- isEOF
unless finished $ do
k =<< getLine
processEachLine k
在這裏,我假設k
函數打印所需的輸出本身。很容易修改processEachLine
來打印輸出,以便k
可以是純粹的。
如果你想要一個'String - > String'類型的函數,你可以很容易地創建一個類似的helper:'processLinesPure ::(String - > String) - > IO(); processLinesPure f = processEachLine(putStrLn。f)' – 2012-04-18 03:00:29
您可以嘗試使用interact
函數。它採用String -> String
類型的函數,並將其轉換爲讀取stdin的動作,將其連續傳遞給該函數,並將該函數返回的字符串寫入stdout。如果你注意不要過度消費輸入字符串,你會得到你所要求的行爲。
'getContents'返回* lazy *字符列表。也許消費功能太嚴格了。 – 2012-04-17 16:38:01