【问题标题】:Why doesn't Haskell sequence these IO actions properly?为什么 Haskell 不能正确地对这些 IO 操作进行排序?
【发布时间】:2013-10-22 09:13:38
【问题描述】:

我的一个朋友问我为什么要学习 Haskell。为了展示 Haskell 的强大功能,我编写了一个显示素数列表的小程序:

main = do
    putStr "Enter the number of prime numbers to display: "
    number <- fmap read getLine :: IO Int
    print . take number . filter isPrime $ [2..]

isPrime :: Integer -> Bool
isPrime n = not . any ((== 0) . mod n) $ [2..floor . sqrt . fromInteger $ n]

程序按预期工作,但有一个小异常。它在从用户获取输入数字后打印提示消息,从而产生如下输出:

12
Enter the number of prime numbers to display: [2,3,5,7,11,13,17,19,23,29,31,37]

为什么 Haskell 没有正确排序 IO 操作?我哪里错了?

【问题讨论】:

    标签: haskell


    【解决方案1】:

    这看起来更像是一个缓冲而不是排序问题。你在哪个平台?您是否尝试过强制无缓冲输出?

    hSetBuffering stdout NoBuffering -- from System.IO
    

    【讨论】:

    • 我正在使用 Glasgow Haskell 编译器。谢谢你。这确实是问题所在。我需要进一步了解 Haskell 中的 IO 操作。
    • 平台我的意思更像是操作系统和终端。通常,stdin 和 stdout 以一种在读取 stdin 时使 stdout 刷新的方式“绑定”,正是为了避免这种问题。 FWIW,您的问题在我的设置中正确缓冲和序列。
    • 哦,我在 Ubuntu 13.10 上使用“终端”。我不确定它是否有一个特定的名称,例如 xterm,但它与 Macintosh OSX 上的终端相同。
    • 编辑: 我在使用 Debian 和 LXTerminal 或 gnome-terminal 时有相同的“解绑”行为。 The C people seem to agree that there isn't an automatic flush
    • 领带的东西是more of a C++ thing。我似乎找不到关于 GHC 的 Haskell 的权威提及,因此假设这里也没有这样的事情是合理的。我的设置(emacs 中的 GHCi)非常有偏见。
    【解决方案2】:

    stdinstdout 是两个不需要任何连接的不同文件。举个例子Unix shell 命令grep:

    $ seq 1 100 | grep 2$ | less
    

    seq 1 100 将数字 1 到 100 打印到其 stdout,即 greps stdin| 将一个命令的 stdout 连接到另一个命令的 stdin)。 grep 然后将与给定正则表达式匹配的行写入其stdoutlesss stdin

    要强制写入stdout(或任何其他文件),请使用hFlush from System.IO

     hFlush stdout
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-21
      • 2022-11-22
      • 2014-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-06
      相关资源
      最近更新 更多