2016-06-06 5 views
3

Как написать следующую функцию без использования обозначения «do»?Haskell: слова подсчитываются из getLine без знака «do»

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

Эти два вопроса ([1] (http://stackoverflow.com/q/16964732/2211273), [2] (http://stackoverflow.com/q/25255260/2211273)) вопросы также касаются desugaring do синтаксиса. [Этот ответ] (http://stackoverflow.com/a/16726740/2211273) также прекрасно объясняет, как это сделать. – Kritzefitz

ответ

3

Вместо использования do, вы можете использовать >> и >>=:

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

Или, что делает его легче читать:

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

Более прямолинейный перевод будет:

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

В основном компилятор преобразует такие do -notation блоки в его монадический эквивалент (используя только >> и >>=). do - это только синтаксический сахар, так что каждый раз не нужно писать >>= и/или переменные mange.

Дополнительные примечания:

  • как сказал @ChadGilbert в his comment, скобки должны быть обернуты вокруг функции, исключая \s -> таким образом, что s могут быть использованы в дальнейшем в программе, например, :

    -- 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 
    
  • Вместо использования putStr и putChar, вы можете использовать putStrLn , Например:

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

В вашем более прямом переводе, не должны ли скобки включать только '' putStr $ show $ length $ words s' statement? Wrapping '(\ s -> putStr $ show $ length $ words s)' означает, что 's' не может использоваться в последующих монадических операциях –

+0

@ChadGilbert: вы имеете в виду как обновленный ответ? Да, в самом деле. Спасибо, что заметили это. –

+1

@ChadGilbert: Я обновил ответ с дополнительной записью, чтобы еще раз объяснить isue, большое спасибо. –