2009-05-07 5 views
65

ich etwas in Haskell tun möchten, die wie folgt aussieht:Haskell „nichts tun“ IO, oder wenn ohne sonst

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

Offensichtlich ist dies nicht legal ist, da es keine else ist. 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 wortreich, aber ich würde mich bei Bedarf damit begnügen. Ich wäre überrascht, wenn es aber nicht eine integrierte Version von nop ist.

Alternativ:

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 schön. Wiederum wäre ich nicht überrascht, etwas zu finden, das bereits existiert.

Was ist der bevorzugte Weg, dies zu tun?

Antwort

90

Der einfachste Weg, einen No-op in einer Monade zu tun ist:

return() 

jedoch für die jeweilige Idiom Sie tun, gibt es eine combinator bereits für Sie gemacht:

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

Diese when combinator verhält sich genau wie Ihr doIf combinator :)

+0

Whoops, dachte ich über return(), aber dachte, dass es tatsächlich zurückkehren würde (d. H. Den Rest des Zeugs im Do-Ausdruck kurzschließen). Mein Fehler. Danke für den Zeiger auf wann. –

+3

Rückkehr ist ein böser Name für sie, yeah :) – bdonlan

+7

@Dave Denken Sie daran, dass 'Rückkehr' in Haskell kein Sprachkonstrukt ist, es ist nur eine Funktion (mit einem schlecht gewählten Namen, wie Bdonian sagt). Die Rückgabe wirkt sich nicht auf den Kontrollfluss aus, oder etwas, das Sie schreiben könnten: 'do {s <- getLine; Rückkehr(); putStrLn s} 'das würde gut funktionieren. –

17

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

In Hoogle, können Sie die Art Signatur eingeben und es wird versuchen, durch die Vereinheitlichung der Arten und Neuordnen Argumente passende Funktionen in den Standardbibliotheken zu finden. In Ihrem Fall können Sie einfach den Typ Ihrer doIf Funktion eingeben: Bool -> IO() -> IO() . when die dritte Antwort ist hier, seine Umkehr unless gibt es auch.