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?
Note that in Haskell if is an expression (which is converted to a value) and not a statement (which is executed) as in many imperative languages. As a consequence, the else is mandatory in Haskell. Since if is an expression, it must evaluate to a result whether the condition is true or false, and the else ensures this.
It's not equivalent to _ , it's equivalent to any other identifier. That is if an identifier is used as a pattern in Haskell, the pattern always matches and the matched value is bound to that identifier (unlike _ where it also always matches, but the matched value is discarded).
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.
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With