Haskell Hero

Haskell Hero es un manual interactivo del lenguaje Haskell para principiantes.

Entrada y salida II

>>, >>=, return

En la lección Entrada y salida hemos hablado de la construcción do.

imprime = do putStrLn "abc"
             putStrLn "def"
             putStrLn "ghi"

es decir, imprime "abc", después imprime "def" y al fin "ghi". Esta secuencia de ordenes también la podemos escribir con el operador >>. La evaluación de la expresión accion1 >> accion2 >> accion3 se evalúa de manera siguiente: Primero se evalúa accion1, después accion2 y al fin accion3. En nuestro ejemplo entonces será:
putStrLn "abc"  >>  putStrLn "def"  >>  putStrLn "ghi"

En el ejemplo anterior las acciones se realizaron independientemente. Sin embargo, nosotros queremos por ejemplo leer un valor del usuario y después utilizar este valor. Es decir, pasar un valor de una acción a la otra. Para esto podemos utilizar el operador >>=. La expresión que lee un valor del usuario y después lo imprime, será la siguiente:

getLine  >>=  putStr

Es decir, lee la entrada del usuario, pasa este valor y aplica a él la función putStr.

Con el valor que hemos pasado podemos realizar más acciones. Solo tenemos que darnos cuenta de que la notación anterior es solamente la expresión

getLine  >>=  \s -> putStr s

convertida en el estilo pointfree. Podemos entonces imprimir el valor dos veces:
getLine  >>=  ( \s -> putStrLn s  >> putStrLn s )

Es decir, lee la entrada, pasa su valor a una función que lo imprime dos veces..

La acción getLine es de tipo IO String que sirve para leer cadenas. La cadena leída se convierte en el valor de la acción getLine que está disponible solamente para el operador (>>=). Si quisiéramos imprimir por ejemplo el resultado de la suma 3 + 5, tenemos que convertirlo primero en String (con la función Show). Sin embargo, esto no es suficiente. El primer parámetro del operador >>= tiene que ser de tipo IO a. Así que hay que convertir el valor de tipo String en un valor de tipo IO String. Y esto lo hace la función return :: a -> IO a (su tipo es aún más general pero para nosotros este es suficiente).

return (show (3 + 5))  >>=  putStr