>()
, то есть пустое действие.
Напишем программу, которая запрашивает строку текста и, если строка равна «РЫБА-МЕЧ», печатает её:
>import Control.Monad
>main = do
> input <- getLine
> when (input == "РЫБА-МЕЧ") $ do
> putStrLn input
Без >when
нам понадобилось бы написать нечто такое:
>main = do
> input <- getLine
> if (input == "РЫБА-МЕЧ")
> then putStrLn input
> else return ()
Как вы видите, функция >when
позволяет выполнить заданное действие в случае, если некоторое условие истинно, и ничего не делать в противном случае.
Функция >sequence
принимает список действий ввода-вывода и возвращает одно действие ввода-вывода, последовательно выполняющее действия из списка. Результат выполнения этого действия – список результатов вложенных действий. Сигнатура типа функции: >sequence
>::
>[IO
>a]
>–>
>IO
>[a]
. Выполним следующее:
>main = do
> a <– getLine
> b <– getLine
> c <– getLine
> print [a,b,c]
То же самое, но с использованием функции >sequence
:
>main = do
> rs <– sequence [getLine, getLine, getLine]
> print rs
Итак, выражение >sequence [getLine, getLine, getLine]
создаст действие ввода-вывода, которое выполнит функцию >getLine
три раза. Если мы свяжем это действие с именем, результат будет представлять собой список результатов действий из изначального списка, в нашем случае – то, что пользователь введёт с клавиатуры.
Функция >sequence
обычно используется, если мы хотим пройтись по списку функциями >print
или >putStrLn
. Вызов >map print [1,2,3,4]
не создаёт действия ввода-вывода – вместо этого создаётся список действий. Такой код на самом деле эквивалентен следующему:
>[print 1, print 2, print 3, print 4]
Если мы хотим преобразовать список действий в действие, то необходимо воспользоваться функцией >sequence
:
>ghci> sequence $ map print [1,2,3,4]
>1
>2
>3
>4
>[(),(),(),()]
Но что это за >[(),(),(),()]
в конце вывода? При выполнении в GHCi действия ввода-вывода помимо самого действия выводится результат выполнения, но только если этот результат не есть >()
. Поэтому при выполнении в GHCi >putStrLn "ха-ха"
просто выводится строка – результатом является >()
. Если же попробовать ввести >getLine
, то помимо собственно ввода с клавиатуры будет выведено введённое значение – результатом является >IO
>String
.
Поскольку применение функции, возвращающей действие ввода-вывода, к элементам списка и последующее выполнение всех полученных действий очень распространено, для этих целей были введены две вспомогательные функции – >mapM
и >mapM_
. Функция >mapM
принимает функцию и список, применяет функцию к элементам списка, сводит элементы в одно действие ввода-вывода и выполняет их. Функция