Haskell "nichts tun" IO, oder wenn ohne sonst

80

Ich möchte in Haskell etwas machen, das so aussieht:

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

Offensichtlich ist dies nicht legal, da es keine gibt else. Eine Alternative, an die ich gedacht habe:

nop :: IO ()
nop = sequence_ []

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

Dies ist ein wenig ausführlich, aber ich würde mich bei Bedarf damit zufrieden geben. Ich wäre überrascht, wenn es keine integrierte Version von gäbe nop.

Alternative:

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

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

Dies ist prägnanter, aber die Syntax ist nicht besonders gut. Auch hier wäre ich nicht überrascht, etwas Eingebautes zu finden, das bereits vorhanden ist.

Was ist der bevorzugte Weg, um dies zu tun?

Dave B.
quelle

Antworten:

114

Der einfachste Weg, ein No-Op in einer Monade zu machen, ist:

return ()

Gleichwertig:

pure ()

Für die jeweilige Redewendung gibt es jedoch bereits einen Kombinator, der für Sie entwickelt wurde:

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

Dieser whenKombinator verhält sich genau wie Ihr doIfKombinator :)

bdonlan
quelle
1
Hoppla, ich habe über return () nachgedacht, aber ich dachte, dass es tatsächlich zurückkehren würde (dh den Rest des Materials im do-Ausdruck kurzschließen). Mein Fehler. Danke für den Hinweis auf wann.
Dave B
6
Rückkehr ist eine Art schlechter Name dafür, ja :)
bdonlan
8
@ Dave Denken Sie daran, dass returnHaskell kein Sprachkonstrukt ist, sondern nur eine Funktion (mit einem schlecht gewählten Namen, wie bdonian sagt). Return hat keinen Einfluss auf den Kontrollfluss oder etwas, das Sie schreiben könnten: do {s <- getLine; return (); putStrLn s}Das würde gut funktionieren .
Tom Lokhorst
Ich werde Not in scope: `when'für test = do (when True (putStrLn "Hello")).
Qwertie
3
Hoppla, whenerfordert import Control.Monadoben in der Datei.
Qwertie
20

Sie können Hoogle verwenden , um Funktionen zu finden, in diesem Fall : when.

In Hoogle können Sie die Typensignatur eingeben. Es wird versucht, übereinstimmende Funktionen in den Standardbibliotheken zu finden, indem die Typen vereinheitlicht und die Argumente neu angeordnet werden.

In Ihrem Fall können Sie einfach den Typ Ihrer doIfFunktion eingeben : Bool -> IO () -> IO () . whenist die dritte Antwort hier, die Umkehrung unlessist auch da.

Tom Lokhorst
quelle