haskell - 使用 getLine 和 putStr 时发生 IO 乱序

标签 haskell user-input monads

我是一个 Haskell 初学者,我刚刚开始了解 Monad,但我还没有真正理解它。我正在编写一个游戏,其中包括询问用户输入并做出响应。这是我的函数的简化版本:

getPoint :: IO Point
getPoint = do
    putStr "Enter x: "
    xStr <- getLine
    putStr "Enter y: "
    yStr <- getLine
    return $ Point (read xStr) (read yStr)


completeUserTurn :: (Board, Player) -> IO (Board, Player)
completeUserTurn (board, player) = do
    putStr $ "Enter some value: "
    var1 <- getLine
    putStr $ "Enter another value: "
    var2 <- getLine
    putStr $ "Enter a point this time: "
    point <- getPoint
    if (... the player entered legal values ...) then do
        putStr $ "This is what would happen if you did that: {stuff} do you want to do that? (y/n) "
        continue <- getLine
        if continue == "y" then
            return (...updated board..., ...updated player...)
        else
            completeUserTurn (board, player)
    else do
        putStr "Invalid Move!\n"
        completeUserTurn (board, player)

所发生的情况是,提示的显示顺序与应该出现在提示之前的文本的顺序不符。

下面是我编译上面的代码后发生的情况的示例:

1
Enter some value: Enter another value:2
3
4
Enter a point this time: Enter x: Enter y: y
Is this correct? (y/n):

粗体是我输入的内容。

显然,我有一些重大的概念错误,但我不知道是什么。请注意,它在解释器中工作正常,但在编译时失败。

最佳答案

正如迈克尔所说,问题在于缓冲。默认情况下,输出会被缓冲,直到您打印换行符(或者如果您的行很长,则直到缓冲区已满),因此在尝试使用 putStr 执行同一行提示时,您最常会看到此问题。就像你正在做的那样。

我建议定义一个像这样的小辅助函数来负责为您进行刷新:

import System.IO

prompt :: String -> IO String
prompt text = do
    putStr text
    hFlush stdout
    getLine

现在你可以简单地做

getPoint = do
    xStr <- prompt "Enter x: "
    yStr <- prompt "Enter y: "
    return $ Point (read xStr) (read yStr)

关于haskell - 使用 getLine 和 putStr 时发生 IO 乱序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13190314/

相关文章:

haskell - 类型类实例重新定义

list - 在 Haskell 中合并 3 个列表

haskell - 在haskell中制作takeUntil函数

java - Integer.parseInt(scanner.nextLine()) 与 scanner.nextInt()

java - 根据用户输入的 java 动态选择两个网卡的 IP 地址,以及演示连接

haskell - 打印自由单子(monad)

sql - Haskell Persistent 加入 Esqueleto

c++ - 为什么 Haskell 对于简单的斐波那契比 C++ 更快

python-3.x - 如何获取用户输入并将其传递给预测模型

f# - 在 F# 的计算表达式中定义新关键字