На этом шаге мы перечислим эти функции.
Конструктор типа IO является экземпляром класса Monad.
Две монадические связывающие функции, являющиеся методами в классе Monad, используются для составления последовательностей операций ввода-вывода.
Другими словами, монада - это абстракция управления.
1. Функция, передающая управление от функции ввода-вывода, представляющей собой первый аргумент данной функции, функции ввода-вывода, представляющей собой второй аргумент данной функции:
(>>):: IO a -> IO b -> IO b
Функция (>>) используется там, где результат первой операции не представляет интереса.
2. Функция, передающая результат функции ввода-вывода, представляющей собой первый аргумент данной функции, в качестве аргумента функции ввода-вывода, представляющей собой второй аргумент данной функции:
(>>=):: IO a -> (a -> IO b) -> IO b
Функция (>>=) передаёт "часть" своего первого параметра в качестве аргумента второго параметра.
3. Функция определяет результат операции ввода-вывода:
return:: a -> IO a
Вначале построим "обычную" функцию:
fun:: String -> String fun = filter isUpper
Теперь построим функцию
main:: IO String
IO String String -> IO String ↓ ↓ main = getLine >>= \s -> return (fun s) ↑ String -> String
В заключение приведем небольшой демонстрационный пример.
-- Демонстрация работы с последовательными операциями -- ввода-вывода (>>=), (>>), return ---------------------------------------------------- -- Функция, перезаписывающая из файла "input" в файл -- "output" только буквы латинского алфавита -------------------------------------------- main1:: IO () main1 = readFile "input" >>= \s -> writeFile "output" (filter isAlpha s) >> putStr "Фильтрация завершилась успешно! \n" ------------------------------------------------------- -- Функция, удаляющая из заданной строки x все символы, -- не являющиеся прописными латинскими буквами. -- Анализ типов используемых функций важен: -- -- getLine:: IO String; -- return :: String -> IO String -- fun :: String -> String -- (>>=) :: IO String -> (String -> IO String) -- -> IO String ------------------------------------- main2:: IO String main2 = getLine >>= \s -> return (fun s) ---------------------------------------- fun:: String -> String fun = filter isUpper ----------------------------------------- -- Префиксная форма записи операции (>>=) --------------------------------------------- main2' = (>>=) getLine (\s -> return (fun s)) ----------------------------------------------- -- Демонстрация реализации простейшего сложения ---------------------------------------------------- main3 = putStr "Введите первое число: " >>= \_ -> readLn >>= \x -> putStr "Введите второе число: " >>= \_ -> readLn >>= \y -> putStrLn $ "Сумма = " ++ show(x+y)
На следующем шаге мы рассмотрим аксиомы монад.