2014-01-14 1 views
14

Я только что наткнулся на то, чего не понимаю.Разница в функциональности 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 

и запустить скрипт с runhaskell и введите тот же вход, backspace удаляет 't', как ожидалось.

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

ответ

20

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

hSetBuffering stdin NoBuffering 

в вашей программе Haskell, вы будете в состоянии воспроизвести поведение GHCI. Если вы

hSetBuffering stdin LineBuffering 

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

+1

вы говорите, что я буду «иметь много нежелательных побочных эффектов», они просто в ghci нежелательны или есть какая-то защита от него в скомпилированной версии - можете ли вы подробнее рассказать об этом? – epsilonhalbe

+0

Можете ли вы это сделать или нет? Я приму этот ответ, как только смогу! – epsilonhalbe

+2

Они не нужны в GHCi. Это будет бесполезно с тем, что GHCi сам читает входы, поэтому, когда вы вводите материал для запуска GHCi, вы увидите, что они отображаются только после нажатия клавиши «Возврат». – kosmikus