Изучай Haskell во имя добра! (Липовача) - страница 125

работает так же, но отбрасывает результат действия ввода-вывода. Она используется, когда нам не важен результат комбинированного действия ввода-вывода.

>ghci> mapM print [1,2,3]

>1

>2

>3

>[(),(),()]

>ghci> mapM_ print [1,2,3]

>1

>2

>3

Функция forever

Функция >forever принимает действие ввода-вывода – параметр и возвращает действие ввода-вывода – результат. Действие-результат будет повторять действие-параметр вечно. Эта функция входит в модуль >Control.Monad. Следующая программа будет бесконечно спрашивать у пользователя строку и возвращать её в верхнем регистре:

>import Control.Monad

>import Data.Char


>main = forever $ do

>   putStr "Введите что-нибудь: "

>   l <– getLine

>   putStrLn $ map toUpper l

Функция forM

Функция >forM (определена в модуле >Control.Monad) похожа на функцию >mapM, но её параметры поменяны местами. Первый параметр – это список, второй – это функция, которую надо применить к списку и затем свести действия из списка в одно действие. Для чего это придумано? Если творчески использовать лямбда-выражения и ключевое слово >do, можно проделывать такие фокусы:

>import Control.Monad


>main = do

>   colors <– forM [1,2,3,4] (\a –> do

>      putStrLn $ "С каким цветом ассоциируется число "

>                 ++ show a ++ "?"

>      color <– getLine

>      return color)

>   putStrLn "Цвета, ассоциирующиеся с 1, 2, 3 и 4: "

>   mapM putStrLn colors

Вот что мы получим при запуске:

>С каким цветом ассоциируется число 1?

>белый

>С каким цветом ассоциируется число 2?

>синий

>С каким цветом ассоциируется число 3?

>красный

>С каким цветом ассоциируется число 4?

>оранжевый

>Цвета, ассоциирующиеся с 1, 2, 3 и 4:

>белый

>синий

>красный

>оранжевый

Анонимная функция (>\a –> do ...) – это функция, которая принимает число и возвращает действие ввода-вывода. Нам пришлось поместить её в скобки, иначе анонимная функция решит, что следующие два действия ввода-вывода принадлежат ей. Обратите внимание, что мы производим вызов >return color внутри блока >do. Это делается для того, чтобы действие ввода-вывода, возвращаемое блоком >do, содержало в себе цвет. На самом деле мы не обязаны этого делать, потому что функция >getLine уже содержит цвет внутри себя. Выполняя >color <– getLine и затем >return color, мы распаковываем результат >getLine и затем запаковываем его обратно, то есть это то же самое, что просто вызвать функцию >getLine. Функция >forM (вызываемая с двумя параметрами) создаёт действие ввода-вывода, результат которого мы связываем с идентификатором >colors. Этот идентификатор – обычный список, содержащий строки. В конце мы распечатываем все цвета, вызывая выражение