Haskell io-streams和`forever`不会向stdout输出任何内容

时间:2016-08-02 10:35:57

标签: haskell

如果我运行此程序,我没有输出到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但是再次尝试了stdout。

1 个答案:

答案 0 :(得分:6)

代码中forever的含义是,必须始终在流中选择每个值。它的类型

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

是一个很大的线索,使用forever构建的计算永远不会返回值:forever的调用者可以任意选择类型b,因此没有程序可以实际承诺提供该类型的值。这也是你的程序攻击的原因。传递给forever的计算会因其效果而重复执行(在这种情况下,选择一个随机数),但是没有传递任何值,因此流永远不会开始。

您不应该需要forever来创建一个继续前进的流。 makeInputStream的行为是每次从流中请求一个值时运行其参数计算,所以你已经在那里重复了。