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


81

Haskellで次のようなことをしたい:

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

がないので、明らかにこれは合法ではありませんelse。私が考えた1つの選択肢:

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

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

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

回答:


116

モナドでno-opを実行する最も簡単な方法は次のとおりです。

return ()

同等に:

pure ()

ただし、実行している特定のイディオムについては、すでに作成されているコンビネータがあります。

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

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


1
おっと、私はreturn()について考えましたが、実際には戻る(つまり、do-expressionの残りの部分を短絡する)と思っていました。私の悪い。いつへのポインタをありがとう。
デイブB

7
リターンはちょっと悪い名前です、ええ:)
bdonlan 2009年

9
@Dave returnHaskellでは言語構造ではなく、単なる関数であることに注意してください(bdonianが言うように、名前の選択が間違っています)。Returnは、制御フローなどには影響しません。次のように記述できます。do {s <- getLine; return (); putStrLn s}これは問題なく実行されます。
Tom Lokhorst

私はのNot in scope: `when'ために取得していtest = do (when True (putStrLn "Hello"))ます。
qwertie 2014

3
おっと、ファイルの先頭にがwhen必要import Control.Monadです。
qwertie 2014

21

この場合、Hoogleを使用して関数を見つけることができますwhen

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.