работает так же, но отбрасывает результат действия ввода-вывода. Она используется, когда нам не важен результат комбинированного действия ввода-вывода.
>ghci> mapM print [1,2,3]
>1
>2
>3
>[(),(),()]
>ghci> mapM_ print [1,2,3]
>1
>2
>3
Функция >forever
принимает действие ввода-вывода – параметр и возвращает действие ввода-вывода – результат. Действие-результат будет повторять действие-параметр вечно. Эта функция входит в модуль >Control.Monad
. Следующая программа будет бесконечно спрашивать у пользователя строку и возвращать её в верхнем регистре:
>import Control.Monad
>import Data.Char
>main = forever $ do
> putStr "Введите что-нибудь: "
> l <– getLine
> putStrLn $ map toUpper l
Функция >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
. Этот идентификатор – обычный список, содержащий строки. В конце мы распечатываем все цвета, вызывая выражение