Haskell io流和'forever'不向标准输出

Haskell io流和'forever'不向标准输出,haskell,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 =

如果我运行此程序,则不会得到输出到
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
import Control.Monad(永远)
将合格的System.IO.Streams作为S导入
导入系统随机(randomRIO)
main::IO()
main=do

是在您的代码中,
永远
的含义是永远需要选择流中的每个值。其类型

forever :: Monad m => m a -> m b
一个重要的线索是,用
永久
构建的计算永远不会返回值:
永久
的调用者可以任意选择类型
b
,因此没有程序能够真正承诺提供该类型的值。这也是您的程序进行类型检查的原因。传递给
forever
的计算会重复执行,以确保其效果(在本例中,选择一个随机数),但不会传递任何值,因此流永远不会继续


你不应该需要一个永远的
来产生一个持续的流。
makeInputStream
的行为是每次从流中请求一个值时都运行其参数计算,因此您已经在那里重复了。

谢谢!我把
永远
看作是一种排序转换,因此它将返回一个
IO Int
(在本例中),然后我可以从中提取一个值。我已将该调用移动到输出流行,它可以按预期工作!:)我一直在说他们应该把它改成
永久::Monad m=>m()->m Void
!“你可以说得面红耳赤……”如果
永远
和类似的设备没有多态返回类型,管道库之类的东西将变得无法穿透,因为
->
的每个应用程序都假定链接的管道或协程具有相同的返回类型。因此,通常在
p>->q>->r
中,除了一之外,所有的都是无限的;有限管道的结果是组合管道的结果,组合管道也是有限的。这是由专业化引起的。同样地,只要你能想到一个
备选方案
实例具有“赛车”的特征,那么
空的
就会像许多自然术语一样。因此,在
async
中,我们可以编写类似于
stillWorking=并发(永远(threadDelay 100000>>putStrLn“仍在工作…”)的代码
conc stillWorking
将告诉我们conc一直在工作。这又是由简单的专门化引起的。