getLine功能与GHCi与runhaskell的区别

eps*_*lbe 17 io haskell ghci runhaskell

我偶然发现了一件我不理解的事情.

如果我使用GHCi并使用getLine我得到以下内容

Prelude> a <- getLine
Test<Backspace>oo<CR> -- the Backspace action results in a '^?'
Prelude> a
"Test\DELoo"
Run Code Online (Sandbox Code Playgroud)

如果我在Haskell文件中写相同的

module Main where

main :: IO ()
main = do a <- getLine
          putStrLn a
Run Code Online (Sandbox Code Playgroud)

并使用runhaskell运行脚本并输入相同的输入,退格按预期删除't'.

为什么会有区别?

kos*_*kus 23

这是由于GHCi和GHC中不同的缓冲行为.GHCI具有使用标准输入(标准输入流)NoBuffering通过默认,GHC和编译的二进制文件/ runhaskell使用LineBuffering默认情况下.如果你明确这样做

hSetBuffering stdin NoBuffering
Run Code Online (Sandbox Code Playgroud)

在您的Haskell程序中,您将能够重现GHCi行为.如果你这样做

hSetBuffering stdin LineBuffering
Run Code Online (Sandbox Code Playgroud)

在GHCi中,你会有很多不必要的副作用,但可以重现这种runhaskell行为.

  • 你说我会有很多不必要的副作用,它们只是在ghci中不受欢迎,还是在编译版本中有某种保护作用 - 你能详细说明一下吗? (2认同)
  • 它们在GHCi中是不受欢迎的.它会混淆GHCi本身读取输入的方式,所以当你输入GHCi运行的东西时,只有在你点击Return键时才会看到它们出现. (2认同)