Разница в функциональности getLine с GHCi против runhaskell

Я только что наткнулся на вещь, которую я не понимаю.

Если я использую GHCi и использую getLine, я получаю следующее

Prelude> a <- getLine
Test<Backspace>oo<CR> -- the Backspace action results in a '^?'
Prelude> a
"Test\DELoo"

Если я пишу тот же в файле Haskell

module Main where

main :: IO ()
main = do a <- getLine
          putStrLn a

и запустите script с помощью runhaskell и введите тот же ввод, backspace удаляет 't', как ожидалось.

Почему существует разница?

Ответы

Ответ 1

Это связано с различной буферизацией в GHCi и GHC. GHCi имеет стандартный (стандартный поток ввода) с использованием NoBuffering по умолчанию, а скомпилированные двоичные файлы GHC/runhaskell используют LineBuffering по умолчанию. Если вы явно делаете

hSetBuffering stdin NoBuffering

в вашей программе Haskell, вы сможете воспроизвести поведение GHCi. Если вы делаете

hSetBuffering stdin LineBuffering

в GHCi, у вас будет много нежелательных побочных эффектов, но можно воспроизвести поведение runhaskell.