2009-05-07 15 views
65

je veux faire quelque chose dans Haskell qui ressemble à ceci:Haskell IO « ne rien faire », ou si, sans autre

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

Il est évident que ce n'est pas juridique, car 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 

Ceci est un peu verbeux, mais je me contenterais de le faire si nécessaire. Je serais surpris s'il n'y avait pas une version intégrée de nop, cependant.

Autre possibilité:

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 est pas particulièrement agréable. Encore une fois, je ne serais pas surpris de trouver quelque chose qui existe déjà.

Quelle est la manière préférée de faire cela?

Répondre

90

La meilleure façon de faire un non-op dans une monade est:

return() 

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" 

cette when Combinator se comporte exactement comme votre doIf Combinator :)

+0

Oups, je pensais à return() mais je pensais que ça reviendrait (c'est-à-dire court-circuiter le reste des choses dans l'expression do). Ma faute. Merci pour le pointeur vers quand. –

+3

return est une sorte de mauvais nom pour ça, ouais :) – bdonlan

+7

@Dave Gardez à l'esprit que 'return' dans Haskell n'est pas une construction de langage, c'est juste une fonction (avec un nom mal choisi, comme le dit bdonian). Le retour n'affecte pas le flux de contrôle, ou quelque chose, vous pouvez écrire: 'do {s <- getLine; revenir(); putStrLn s} 'qui s'exécuterait très bien. –

17

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

Dans Hoogle, vous pouvez entrer la signature de type et essayer de trouver des fonctions correspondantes dans les bibliothèques standard en unifiant les types et en réorganisant les arguments. Dans votre cas, vous pouvez simplement entrer le type de votre doIf fonction: Bool -> IO() -> IO() . when est la troisième réponse ici, son unless inverse est là aussi.