web-dev-qa-db-ja.com

Haskell IOを「何もしない」、または他にない場合

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

これはより簡潔ですが、構文は特にニースではありません。繰り返しますが、すでに存在している組み込みのものを見つけても驚かないでしょう。

これを行うための好ましい方法は何ですか?

74
Dave B

モナドでノーオペレーションを行う最も簡単な方法は次のとおりです。

return ()

しかし、あなたがしている特定のイディオムのために、すでにあなたのために作られたコンビネーターがあります:

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

この when コンビネーターはdoIfコンビネーターとまったく同じように動作します:)

104
bdonlan

Hoogle を使用して関数を検索できます。この場合はwhenです。

Hoogleでは、タイプシグネチャを入力できます。タイプを統一し、引数を並べ替えることにより、標準ライブラリで一致する関数を見つけようとします。

あなたの場合は、単にdoIf関数のタイプを入力できます: Bool-> IO()-> IO =()whenは3番目の答えであり、その逆のunlessもあります。

19
Tom Lokhorst