Forum Programmation.autre Haskell, problème de strictitude de do

Posté par  .
Étiquettes :
5
15
déc.
2011

(Ségolène me manque)

Voila, je me demandais, considérez le brin de code suivant :

module Main where
import Graphics.UI.GLUT

main :: IO ()
main = do 
    _ <- getArgsAndInitialize
    _ <- createWindow "test"
    displayCallback $= clear [ColorBuffer] >> flush
--    displayCallback $= do clear [ColorBuffer] ; flush
    mainLoop


La ligne commentée me semblait équivalente à sa voisine du dessus, et pourtant la première ligne n'initialise pas le fond de la fenêtre crée, la seconde, oui. Comment ça ce fait ?

Ajout :

main = getArgsAndInitialize >>  createWindow "test" >> displayCallback $= ( clear [ColorBuffer] >> flush) >> mainLoop


Celui ci aussi fonctionne pareil… J'y comprend rien.
  • # parenthese dans l'ajout mais pas dans le modele

    Posté par  . Évalué à 0.

    syntaxiquement tes lignes ne sont deja pas les memes

    dans l'exemple :

    $= clear [ColorBuffer] >> flush

    $= do clear [ColorBuffer] ; flush

    dans l'ajout

    $= ( clear [ColorBuffer] >> flush )

    apres j'y connais rien en haskell, mais comme les choses sont ecrites differents, ton probleme vient peut-etre de là

    • [^] # Re: parenthese dans l'ajout mais pas dans le modele

      Posté par  . Évalué à 3. Dernière modification le 16 décembre 2011 à 17:58.

      comme les choses sont ecrites differents, ton probleme vient peut-etre de là

      Merci Captain Obvious ;)

      J'y connais rien en haskell non plus mais je suppose que Zylabon cherche bien à savoir pourquoi ça ne fait pas la même chose.

  • # Priorité des opérateurs

    Posté par  . Évalué à 4. Dernière modification le 18 décembre 2011 à 00:52.

    La ligne :

    displayCallback $= clear [ColorBuffer] >> flush
    
    

    Est analysée par le compilateur comme :
    (displayCallback $= clear [ColorBuffer]) >> flush
    
    

    Donc le flush a lieu dans l'action du main, pas dans le
    displayCallback qui survient plus tard. Donc le displayCallback effectue pleins de "clear [ColorBuffer]", sans jamais flush.

    À l'opposé :

    displayCallback $= do clear [ColorBuffer] ; flush
    
    

    Devient :
    displayCallback $= (clear [ColorBuffer] >> flush)
    
    

    Ce qui est vraisemblablement ce que tu veux vraiment faire.

    Cela vient du fait que $= est prioritaire sur >> dans la définition.

    Pour voir les priorités :

    Prelude> import Graphics.UI.GLUT
    Prelude Graphics.UI.GLUT> :info ($=)
    class HasSetter s where ($=) :: s a -> a -> IO ()
            -- Defined in Data.StateVar
    infixr 2 $=
    Prelude Graphics.UI.GLUT> :info (>>)
    class Monad m where
      ...
      (>>) :: m a -> m b -> m b
      ...
            -- Defined in GHC.Base
    infixl 1 >>
    Prelude Graphics.UI.GLUT>
    
    
    • [^] # Re: Priorité des opérateurs

      Posté par  . Évalué à 1.

      Effectivement, ça parait tellement logique… Dire que je voyais là un problème de paresse.
      À vrai dire, je n'avais jamais trop prêté attention à l'importance des priorités et des associativité des opérateurs infixes. Et d'ailleurs, je vais même éviter de jouer avec, ça semble générateur de bugs. Les notations préfixes ne sont jamais ambigües.

      Merci beaucoup :)

      Please do not feed the trolls

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.