2016-06-06 3 views
3

Comment écrire la fonction suivante sans utiliser la notation "do"?Haskell: les mots comptent à partir d'un getLine sans la notation "do"

wordsCount = do 
    putStr "Write a line and press [enter]:\n" 
    s <- getLine 
    putStr $ show $ length . words $ s 
    putChar '\n' 
+1

Ces deux questions ([1] (http://stackoverflow.com/q/16964732/2211273), [2] (http://stackoverflow.com/q/25255260/2211273)) sont aussi des questions sur la syntaxe desugaring do. [Cette réponse] (http://stackoverflow.com/a/16726740/2211273) explique aussi bien comment le faire. – Kritzefitz

Répondre

3

Au lieu d'utiliser do, vous pouvez utiliser >> et >>=:

wordsCount = putStr "Write a line and press [enter]:\n" >> getLine >>= putStr . show . length . words >> putChar '\n' 

Ou ce qui rend plus facile à lire:

wordsCount = putStr "Write a line and press [enter]:\n" >> 
    getLine >>= 
    putStr . show . length . words >> 
    putChar '\n' 

Une traduction plus straight-forward serait:

wordsCount = putStr "Write a line and press [enter]:\n" >> 
    getLine >>= 
    \s -> (putStr $ show $ length $ words s) >> 
    putChar '\n' 

Fondamentalement, le compilateur convertit do -notation blocs à son équivalent monadique (en utilisant seulement >> et >>=). do est seulement sucre syntaxique de telle sorte que l'on n'a pas besoin d'écrire >>= à chaque fois et/ou des variables de gestion.

Notes complémentaires:

  • comme @ChadGilbert dit dans his comment, la parenthèse doit être enroulé autour de la fonction, à l'exclusion de la \s -> telle que la s peut être utilisé plus tard dans le programme, par exemple :

    -- This is not an equivalent program 
    wordsCount = putStr "Write a line and press [enter]:\n" >> 
        getLine >>= 
        \s -> (putStr $ show $ length $ words s) >> 
        putChar '\n' >> 
        putStrLn s -- repeat s 
    
  • Au lieu d'utiliser putStr et putChar, vous pouvez utiliser putStrLn . Par exemple:

    wordsCount = putStr "Write a line and press [enter]:\n" >> 
        getLine >>= 
        putStrLn . show . length . words 
    
+0

Dans votre traduction plus directe, les parenthèses ne devraient-elles pas simplement contenir l'instruction 'putStr $ show $ longueur $ words s'? Wrapping '(\ s -> putStr $ show $ longueur $ mots s)' signifie que 's' n'est pas utilisable dans les instructions monadiques suivantes –

+0

@ChadGilbert: vous voulez dire comme la réponse mise à jour? Oui en effet. Merci d'avoir repéré ça. –

+1

@ChadGilbert: J'ai mis à jour la réponse avec une note supplémentaire pour expliquer davantage la question, merci beaucoup. –