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

>(), то есть пустое действие.

Напишем программу, которая запрашивает строку текста и, если строка равна «РЫБА-МЕЧ», печатает её:

>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 принимает список действий ввода-вывода и возвращает одно действие ввода-вывода, последовательно выполняющее действия из списка. Результат выполнения этого действия – список результатов вложенных действий. Сигнатура типа функции: >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_. Функция >mapM принимает функцию и список, применяет функцию к элементам списка, сводит элементы в одно действие ввода-вывода и выполняет их. Функция