web-dev-qa-db-fra.com

Haskell "ne fait rien" IO, ou si sans autre

Je veux faire quelque chose à Haskell qui ressemble à ceci:

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

Évidemment, ce n'est pas légal car il n'y a pas de else. Une alternative à laquelle j'ai pensé:

nop :: IO ()
nop = sequence_ []

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

C'est un peu bavard, mais je me contenterais de cela si nécessaire. Je serais surpris s'il n'y avait pas de version intégrée de nop.

Alternativement:

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

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

C'est plus concis, mais la syntaxe n'est pas particulièrement agréable. Encore une fois, je ne serais pas surpris de trouver quelque chose de intégré qui existe déjà.

Quelle est la meilleure façon de procéder?

74
Dave B

La façon la plus simple de faire un no-op dans une monade est:

return ()

Cependant, pour l'idiome particulier que vous faites, il existe déjà un combinateur pour vous:

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

Ce quand combinateur se comporte exactement comme votre combinateur doIf :)

104
bdonlan

Vous pouvez utiliser Hoogle pour trouver des fonctions, dans ce cas: when.

Dans Hoogle, vous pouvez entrer la signature de type et il essaiera de trouver les fonctions correspondantes dans les bibliothèques standard en unifiant les types et en réorganisant les arguments.

Dans votre cas, vous pouvez simplement saisir le type de votre fonction doIf: Bool -> IO () -> IO = () . when est la troisième réponse ici, son inverse unless est là aussi.

19
Tom Lokhorst