【问题标题】:Haskell "do nothing" IO, or if without elseHaskell“什么都不做” IO,或者如果没有其他
【发布时间】:2010-10-24 09:17:11
【问题描述】:

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

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

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

最好的方法是什么?

【问题讨论】:

    标签: haskell syntax io


    【解决方案1】:

    在 monad 中执行无操作的最简单方法是:

    return ()
    

    等价:

    pure ()
    

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

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

    这个when 组合器的行为与您的doIf 组合器完全一样:)

    【讨论】:

    • 哎呀,我想过 return () 但认为它实际上会返回(即短路 do 表达式中的其余内容)。我的错。感谢您指向何时。
    • return 对它来说是个坏名字,是的 :)
    • @Dave 请记住,Haskell 中的return 不是语言结构,它只是一个函数(正如 bdonian 所说,名称选择不当)。 Return 不会影响控制流,或者其他什么,你可以写:do {s &lt;- getLine; return (); putStrLn s} 会执行得很好。
    • 我收到了Not in scope: `when' for test = do (when True (putStrLn "Hello"))
    • 糟糕,when 需要 import Control.Monad 在文件顶部。
    【解决方案2】:

    您可以使用Hoogle 来查找函数,在本例中为:when

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

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

    【讨论】:

      猜你喜欢
      • 2015-01-13
      • 2015-06-12
      • 1970-01-01
      • 2017-07-03
      • 2012-10-14
      • 2023-01-30
      • 2013-02-07
      • 2020-04-23
      • 1970-01-01
      相关资源
      最近更新 更多