La manera más simple sería hacer lo que hacen wget y otros programas: imprimir un retorno de carro y un código de borrado ANSI antes de la información de progreso, volviendo el cursor al inicio de la línea y reemplazando el texto existente . Por ejemplo:
import Control.Monad
import Control.Concurrent
import System.IO
import Text.Printf
putProgress :: String -> IO()
putProgress s = hPutStr stderr $ "\r\ESC[K" ++ s
drawProgressBar :: Int -> Rational -> String
drawProgressBar width progress =
"[" ++ replicate bars '=' ++ replicate spaces ' ' ++ "]"
where bars = round (progress * fromIntegral width)
spaces = width - bars
drawPercentage :: Rational -> String
drawPercentage progress = printf "%3d%%" (truncate (progress * 100) :: Int)
main :: IO()
main = do
forM_ [0..10] $ \i -> do
let progress = fromIntegral i/10
putProgress $ drawProgressBar 40 progress ++ " " ++ drawPercentage progress
threadDelay 250000
putProgress "All done."
hPutChar stderr '\n'
La clave aquí es que no impresión de una nueva línea, para que pueda volver al principio de la línea en la siguiente actualización del progreso.
Por supuesto, usted podría imprimir el porcentaje aquí y deje caer la barra, pero hay un bar es más fresco :)
¿se permite volver a dibujar 'cls'? –
también, puede usar alguna forma de 'echo' que no imprime salto de línea, por lo tanto, había un carácter de control' back one symbol erase', por lo que puede hacer una animación rotativa (hecha de -/| \) –
Mi Haskell está algo oxidado, por decir lo menos, pero si mal no recuerdo, si usas putStr con un \ r, harás un retorno de carro sin un salto de línea que te permita sobrescribir la línea en la que estás. –