Haskell "do nothing" IO, or if without else

42,203

Solution 1

The easiest way to do a no-op in a monad is:

return ()

Equivalently:

pure ()

However, for the particular idiom you're doing, there's a combinator already made for you:

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

This when combinator behaves exactly like your doIf combinator :)

Solution 2

You can use Hoogle to find functions, in this case: when.

In Hoogle, you can enter the type signature, and it will try to find matching functions in the standard libraries by unifying the types and reordering arguments.

In your case, you can simply enter the type of your doIf function: Bool -> IO () -> IO () . when is the third answer here, its reverse unless is there also.

Share:
42,203
Dave B
Author by

Dave B

Updated on November 03, 2020

Comments

  • Dave B
    Dave B over 3 years

    I want to do something in Haskell that looks like this:

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

    Obviously this isn't legal since there's no else. One alternative I've thought of:

    nop :: IO ()
    nop = sequence_ []
    
    main2 = do s <- getLine
               if s == "foo" then putStr "You entered foo" else nop
    

    This is a little verbose, but I would settle for it if necessary. I would be surprised if there weren't a built-in version of nop, though.

    Alternatively:

    doIf :: Bool -> IO () -> IO ()
    doIf b m = if b then m else nop
    
    main3 = do s <- getLine
               doIf (s == "foo") (putStr "You entered foo")
    

    This is more concise, but the syntax is not particularly nice. Again, I wouldn't be surprised to find something built-in that already exists.

    What's the preferred way to do this?