2012-10-22 5 views
7
import Data.Char 

main = do 
    c <- getChar 
    if not $ isUpper c 
     then do putChar $ toUpper c 
       main 
     else putChar '\n' 

Caricamento ed esecuzione in GHCi:Perché l'esecuzione di getChar in un terminale è diversa dall'esecuzione in GHCi?

λ> :l foo.hs 
Ok, modules loaded: Main. 
λ> main 
ñÑsSjJ44aAtTR 
λ> 

Questo consuma un carattere alla volta.

Ma in un terminale:

[~ %]> runhaskell foo.hs 
utar,hkñm-Rjaer 
UTAR,HKÑM- 
[~ %]> 

consuma una riga alla volta.

Perché si comporta in modo diverso?

risposta

11

Quando si esegue un programma nel terminale utilizza LineBuffering per impostazione predefinita, ma in ghci è impostato su NoBuffering. Puoi leggere su di esso here. Dovrai rimuovere il buffering da stdin e stdout per ottenere il comportamento simile.

import Data.Char 
import System.IO 

main = do 
    hSetBuffering stdin NoBuffering 
    hSetBuffering stdout NoBuffering 
    foo 
foo = do 
    c <- getChar 
    if not $ isUpper c 
     then do putChar $ toUpper c 
       foo 
     else putChar '\n' 
+0

Quindi 'ghci' usa' NoBuffering' di default, ma il facto in ogni programma è 'LineBuffering', sì? – helq

+0

Sì nel terminale è LineBuffering per impostazione predefinita. – Satvik

+1

C'è una differenza tra disabilitare il buffering e il flushing, cioè sostituire 'putChar x' con' do {putChar x; hflush stdout; } '? – David