Haskell "no hace nada" IO, o si no tiene más

81

Quiero hacer algo en Haskell que se vea así:

main1 = do s <- getLine
           if s == "foo" then putStr "You entered foo"

Obviamente, esto no es legal ya que no existe else. Una alternativa en la que he pensado:

nop :: IO ()
nop = sequence_ []

main2 = do s <- getLine
           if s == "foo" then putStr "You entered foo" else nop

Esto es un poco detallado, pero me conformaría con ello si fuera necesario. Sin embargo, me sorprendería que no hubiera una versión incorporada de nop.

Alternativamente:

doIf :: Bool -> IO () -> IO ()
doIf b m = if b then m else nop

main3 = do s <- getLine
           doIf (s == "foo") (putStr "You entered foo")

Esto es más conciso, pero la sintaxis no es particularmente agradable. Una vez más, no me sorprendería encontrar algo integrado que ya exista.

¿Cuál es la forma preferida de hacer esto?

Dave B
fuente

Respuestas:

116

La forma más sencilla de realizar una operación no operativa en una mónada es:

return ()

Equivalentemente:

pure ()

Sin embargo, para el idioma en particular que estás haciendo, ya hay un combinador hecho para ti:

import Control.Monad
main = do s <- getLine
          when (s == "foo") $ putStr "You entered foo"

Este whencombinador se comporta exactamente como su doIfcombinador :)

bdonlan
fuente
1
Vaya, pensé en return () pero estaba pensando que realmente regresaría (es decir, cortocircuitaría el resto de las cosas en la expresión do). Culpa mía. Gracias por indicarnos cuándo.
Dave B
7
volver es un mal nombre para eso, sí :)
bdonlan
9
@Dave Tenga en cuenta que returnen Haskell no es una construcción de lenguaje, es solo una función (con un nombre mal elegido, como dice bdonian). El retorno no afecta el flujo de control, o algo, podría escribir: do {s <- getLine; return (); putStrLn s}eso se ejecutaría bien.
Tom Lokhorst
Me estoy haciendo Not in scope: `when'para test = do (when True (putStrLn "Hello")).
Qwertie
3
Vaya, whenrequiere import Control.Monaden la parte superior del archivo.
Qwertie
21

Puede utilizar Hoogle para encontrar funciones, en este caso: when.

En Hoogle, puede ingresar la firma del tipo, e intentará encontrar funciones coincidentes en las bibliotecas estándar unificando los tipos y reordenando los argumentos.

En su caso, simplemente puede ingresar el tipo de su doIffunción: Bool -> IO () -> IO () . whenes la tercera respuesta aquí, su reverso unlesstambién está allí.

Tom Lokhorst
fuente