Haskell“ do nothing”IO,或者 if without else

我想在哈斯克尔做这样的事情:

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

显然,这是不合法的,因为没有 else。一个替代方案,我已经想到:

nop :: IO ()
nop = sequence_ []


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

这有点冗长,但如果有必要,我会接受的。不过,如果没有内置版本的 nop,我会感到惊讶。

或者:

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


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

这样更简洁,但语法不是特别好。同样,如果发现已经存在内置的东西,我也不会感到惊讶。

这样做的首选方法是什么?

45281 次浏览

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 :)

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.