2012-03-17 14 views
7

Soy bastante nuevo en Haskell, y me gustaría seguir leyendo líneas desde la consola hasta el final de la transmisión, y generando todo lo que recibo en mayúsculas. Hasta el momento, tengoLeer hasta el final de la transmisión en haskell

import Data.Char 

main = myLoop 

myLoop = do inp <- getLine 
      if (inp == "x") 
       then putStrLn "Bye!" 
       else do putStrLn(map toUpper inp) 
         myLoop 

Sin embargo, me parece que no puede encontrar la manera de evitar la condición if (inp == "x") y reemplazarlo con un estado de fin de flujo.

En resumen, estoy buscando el equivalente a Haskell while (cin >> line) en C++

+0

Debe seleccionar la respuesta de Dave4420: indica que las personas que tienen el problema describen cuál de las soluciones realmente lo responde. – Titou

Respuesta

8

Esto va mucho más allá de lo que realmente está pidiendo, pero yo uso este patrón mucho: interact:

myFun :: String -> String 
myFun = ... 

main = interact (unlines . myFun . lines) 

Su función myFun será ejecutado en contra de cada línea de entrada estándar y la resultado enviado a la salida estándar.

+0

Supongo que es una curiosidad de ghci, pero 'main = interact (unlines. Map (map toUpper). Lines) >> putStrLn" bye "' no funciona en el interior ghci - es como 'interactive toUpper' - pero hace lo que Kshitij Mehta quiere si compila o usa runhaskell – applicative

+0

@applicative lo que no funciona al respecto? Lo único extraño que encontré es que en lugar de usar CTRL-D para señalar el final de la entrada, debes interrumpirlo con CTRL-C. Lo mismo vale para 'ghc -e" interact (unlines. Map (map toUpper). Lines) >> putStrLn \ "bye \" "' –

+0

Dentro de ghci, la primera línea "first line" se ve así: 'fFiIrRsStT LLiInNeE' – applicative

15

Uso isEOF de System.IO.

import System.IO (isEOF) 
import Data.Char 

main = myLoop 

myLoop = do done <- isEOF 
      if done 
       then putStrLn "Bye!" 
       else do inp <- getLine 
         putStrLn (map toUpper inp) 
         myLoop 
+0

Podría ser un estilo ligeramente mejor usar 'a menos que done $ do ...' ya que no se realiza un cálculo significativo en la rama 'done == True'. –

+0

Responde la pregunta + da una solución que funciona en archivos realmente largos – Titou

4

También puede confiar en IO perezoso.

import Data.Char 

main :: IO() 
main = do 
    inp <- getContents 
    let ls = lines inp 
     upcased = map (map toUpper) ls 
    mapM_ putStrLn upcased 
1

Otra opción es utilizar when cuya documentación se puede encontrar here:

import System.IO (isEOF) 
import Data.Char (toUpper) 
import Control.Monad (forever, when) 
import System.Exit (exitSuccess) 
main = myLoop 

myLoop = forever $ do 
       done <- isEOF 
       when done $ putStrLn "Bye!" >> exitSuccess 
       inp <- getLine 
       putStrLn (map toUpper inp) 
       myLoop 

De lo contrario, la respuesta es idéntica a the one by @dave4420.

+0

Me encanta tu respuesta, hombre. – Ch3shire

Cuestiones relacionadas