2016-08-02 18 views
2

如果我運行這個程序,我沒有得到任何輸出stdoutHaskell的IO流和`forever`不產生輸出到stdout

import Control.Monad (forever) 
import qualified System.IO.Streams as S 
import System.Random (randomRIO) 

main :: IO() 
main = do 
    is <- S.makeInputStream $ forever $ (randomRIO (1, 100) :: IO Int) 
    os <- printStream =<< S.read is 
    return() 

printStream :: Maybe Int -> IO() 
printStream Nothing = putStrLn "Nada!" 
printStream (Just a) = putStrLn $ show a 

我已經嘗試設置使用System.IO.hSetBuffering緩衝,以LineBufferingNoBuffering,但仍沒有輸出。我試過cat | ~/local/bin/program | cat,但再次,標準輸出中沒有任何東西。

回答

6

代碼中forever的含義是,需要永遠選擇每個值在流中。它的類型

forever :: Monad m => m a -> m b 

是一個很大的線索與forever建立了一個計算永遠沒有返回值:的forever來電到達挑類型b隨意,所以沒有程序實際上可以承諾提供該類型的值。這也是爲什麼你的程序typechecks。您傳遞給forever的計算會因其效果(在這種情況下,選擇一個隨機數)而重複執行,但沒有值會傳遞,因此流不會繼續。

您不應該需要forever來製作一個繼續流。 makeInputStream的行爲是每次從流中請求一個值時運行它的參數計算,所以你已經有了你的重複。

+0

謝謝!我正在讀'永遠'作爲一種轉換,所以它會返回一個'IO Int'(在這種情況下),然後我可以從中提取一個值。我已將該調用移至輸出流行,並按預期工作! :) –

+1

我一直在說他們應該把它改爲永遠:: Monad m => m() - > m Void'! – Gurkenglas

+0

「你可以說話,直到你臉色發青......」 – pigworker