87 votes

Haskell "do nothing" IO, ou if sans else

Je veux faire quelque chose en Haskell qui ressemble à ça :

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

Évidemment, ce n'est pas légal puisqu'il n'y a pas 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 verbeux, mais je m'en contenterai si nécessaire. Je serais surpris s'il n'y avait pas une version intégrée de nop mais

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 d'intégré qui existe déjà.

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

126voto

bdonlan Points 90068

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

return ()

De manière équivalente :

pure ()

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

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

Este when se comporte exactement comme votre doIf combinateur :)

1 votes

Oups, j'ai pensé à return () mais je pensais qu'il retournerait effectivement (c'est-à-dire qu'il court-circuiterait le reste des choses dans l'expression do). C'est ma faute. Merci pour l'indication de when.

7 votes

Le retour est un peu un mauvais nom pour ça, ouais :)

9 votes

Dave Gardez à l'esprit que return en Haskell n'est pas une construction du langage, c'est juste une fonction (avec un nom mal choisi, comme le dit bdonian). Return n'affecte pas le flux de contrôle, ou quelque chose comme ça, on pourrait écrire : do {s <- getLine; return (); putStrLn s} qui s'exécuterait très bien.

21voto

Tom Lokhorst Points 7733

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

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

Dans votre cas, vous pouvez simplement entrer le type de votre doIf fonction : [Bool -> IO () -> IO ()](http://haskell.org/hoogle/?hoogle=Bool%20-%3E%20IO%20()%20-%3E%20IO%20()) . when est la troisième réponse ici, son inverse unless est là aussi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X