我有一个简单的程序,该程序仅从用户处获取一个字符串和一个密钥,并使用凯撒密码函数对字符串进行加密。该函数本身起作用,所以我不会显示源代码。问题是,当编译器编译程序时,它将允许我输入所有的getLines,然后在输入所有内容之后,程序将打印所有的putStr和putStrLn,然后关闭。仅当使用“ runhaskell”执行程序或将其编译并执行为exe时才发生这种情况。不在口译员中。这是程序:
main = do
choice <- prompt "Would you like to encrypt (1) or decrypt (2)? "
if choice == "1" then do
encrypt <- prompt "Enter code for encryption: "
k <- prompt "Enter key for the code: "
let key = read k in
putStrLn ("Encrypted message: " ++ (caesar key encrypt) ++ "\n")
else do
decrypt <- prompt "Enter code for decryption: "
k <- prompt "Enter key for the code: "
let key = read k in
putStrLn ("Decrypted message: " ++ (caesar (-key) decrypt) ++ "\n")
getLine
prompt str = do
putStr str
getLine
在解释器中运行时的输出:
Prelude Main> main
Would you like to encrypt (1) or decrypt (2)? 1 <- the one is user input
Enter code for encryption: Hello world <- user input
Enter key for the code: 2 <- user input
Encrypted message: Jgnnq"yqtnf <- program output
编译后执行时的输出:
1 <- user has to input before the console is printed out
Hello world <--┘
2 <--┘
Would you like to encrypt (1) or decrypt (2)? Enter code for encryption: Enter key for the code: Encrypted message: Jgnnq"yqtnf
我忽略了关于putStrLn和putStr的内容吗?它们是否仅是由于功能或其他原因而执行?
此外,我创建的“提示”功能也不是问题,因为我用它们各自的putStr和getLine替换了所有的hint用法,并且仍然做同样的事情。
答案 0 :(得分:7)
runhaskell
和ghci
旨在尽可能快地启动您的程序,而不再强调运行程序的效率。因此,与ghc
相比,它们做出了许多次优效率决策,而在此困扰您的是,它们默认情况下不对标准输入或输出使用任何缓冲,而ghc
使用更高效的决策。默认情况下,行缓冲。由于您从未打印过prompt
结束的行,因此在编译版本中,缓冲区不会显示给用户...直到打印程序结束时到达putStrLn
为止。行结尾,整个缓冲区立即显示。
您有一些选择:
System.IO
,并在hSetBuffering stdout NoBuffering
的开头使用main
。System.IO
之前,导入hFlush stdout
并使用getLine
。putStrLn
而不是putStr
。