Haskell"无所事事"IO,或者如果没有别的话

Dav*_*e B 75 io syntax haskell

我想在Haskell中做一些看起来像这样的事情:

main1 = do s <- getLine
           if s == "foo" then putStr "You entered foo"
Run Code Online (Sandbox Code Playgroud)

显然这是不合法的,因为没有else.我想到的另一种选择:

nop :: IO ()
nop = sequence_ []

main2 = do s <- getLine
           if s == "foo" then putStr "You entered foo" else nop
Run Code Online (Sandbox Code Playgroud)

这有点冗长,但如果有必要,我会满足.如果没有内置版本,我会感到惊讶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")
Run Code Online (Sandbox Code Playgroud)

这更简洁,但语法不是特别好.再一次,我不会惊讶地发现已经存在的内置内容.

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

bdo*_*lan 107

在monad中执行no-op的最简单方法是:

return ()
Run Code Online (Sandbox Code Playgroud)

但是,对于你正在做的特定习语,已经为你制作了一个组合器:

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

组合子的行为完全像你doIf组合子:)

  • @Dave请记住,Haskell中的`return`不是一种语言结构,它只是一个函数(有一个选择错误的名字,正如bdonian所说).返回不影响控制流,或者你可以写的东西:`do {s < - getLine; return(); putStrLn s}`执行得很好. (8认同)
  • 返回对它来说是一个坏名字,是的:) (4认同)
  • 糟糕,`when`需要在文件顶部导入`Control.Monad`. (2认同)

Tom*_*rst 19

您可以使用Hoogle查找功能,在这种情况下:when.

在Hoogle中,您可以输入类型签名,它将尝试通过统一类型和重新排序参数来查找标准库中的匹配函数.

在您的情况下,您只需输入您的doIf函数类型:Bool - > IO() - > IO() .when这是第三个答案,它的反面unless也是如此.