Система ввода - вывода в Haskell является чисто функциональной, но при этом обладает выразительной мощью обычных языков программирования. Чтобы достичь этого, Haskell использует монаду для интеграции операций ввода - вывода в чисто функциональный контекст.
Монада ввода - вывода используется в Haskell как связующее звено между значениями, присущими функциональному языку, и действиями, характеризующими операции ввода - вывода и императивное программирование в общем. Порядок вычисления выражений в Haskell ограничен только зависимостями данных; реализация обладает значительной свободой в выборе этого порядка. Действия, тем не менее, должны быть упорядочены определенным образом для выполнения программы и, в частности, ввода - вывода, для того чтобы быть правильно интерпретированы. В Haskell монада ввода - вывода предоставляет пользователю способ указать последовательное связывание действий, и реализация обязана соблюдать этот порядок.
Термин монада происходит из отрасли математики, известной как теория категорий. Однако, с точки зрения программиста Haskell , лучше думать о монаде как об абстрактном типе данных. В случае монады ввода - вывода абстрактными значениями являются упомянутые выше действия. Некоторые операции являются примитивными действиями, соответствующими обычным операциям ввода - вывода. Специальные операции (методы в классе , см. раздел 6.3.6) последовательно связывают действия, соответствующие последовательным операторам (таким как точка с запятой) в
Хотя Haskell обеспечивает довольно сложные средства ввода - вывода, определенные в библиотеке IO, многие программы на Haskell можно писать, используя лишь несколько простых функций, которые экспортируются из Prelude и которые описаны в этом разделе.
Все функции ввода - вывода, описанные здесь, имеют дело с символами. Обработка символа новой строки будет различаться в различных системах. Например, два символа ввода, возврат каретки и перевод строки, могут быть считаны как один
Далее, вспомним, что String является синонимом для [Char] (раздел 6.1.2).
Эти функции записывают в стандартное устройство вывода (обычно это пользовательский терминал).
putChar :: Char -> IO () putStr :: String -> IO () putStrLn :: String -> IO () - добавляет символ новой строки print :: Show a => a -> IO ()
Функция print выводит значение любого пригодного для печати типа на стандартное устройство вывода. Пригодные для печати типы - это те типы, которые являются экземплярами класса Show; print преобразует значения в строки для вывода, используя операцию show, и добавляет
Например, программа для печати первых 20 целых чисел и их степеней 2 могла быть записана так:
main = print ([(n, 2^n) | n >- [0..19]])
Эти функции считывают данные из стандартного устройства ввода (обычно это пользовательский терминал).
getChar :: IO Char getLine :: IO String getContents :: IO String interact :: (String -> String) -> IO () readIO :: Read a => String -> IO a readLn :: Read a => IO a
Операция getChar вызывает исключение (раздел 7.3) при появлении isEOFError, который распознает это исключение, определен в библиотеке IO. Операция getLine вызывает исключение при тех же обстоятельствах, что и hGetLine, определенная в библиотеке IO.
Операция getContents возвращает весь пользовательский ввод в виде одной строки, которая считывается лениво, по мере надобности. Функция interact принимает в качестве аргумента функцию типа String -> String. Весь ввод из стандартного устройства ввода передается этой функции в качестве аргумента, а результирующая строка выводится на стандартное устройство вывода.
Обычно операция read из класса Read используется для преобразования строки в значение. Функция readIO похожа на read, за исключением того, что она предупреждает монаду ввода - вывода об ошибке разбора вместо завершения программы. Функция readLn объединяет getLine и readIO.
Следующая программа просто удаляет все символы, не являющиеся ASCII, из своего isAscii определена в библиотеке.)
main = interact (filter isAscii)
Эти функции оперируют файлами символов. Файлы указываются посредством строк, используя некоторый, зависящий от реализации, метод разрешения строк как имен файлов.
Функции writeFile и appendFile соответственно записывают или добавляют в конец строку, свой второй аргумент, в файл, свой первый аргумент. Функция считывает файл и возвращает содержимое файла в виде строки. Файл считывается лениво, по требованию, как в getContents.
type FilePath = String writeFile :: FilePath -> String -> IO () appendFile :: FilePath -> String -> IO () readFile :: FilePath -> IO String
Обратите внимание, что writeFile и appendFile записывают литеральную строку в файл. Для того чтобы записать значение любого пригодного для печати типа, как в print, сначала используется функция show для преобразования значения в строку.
main = appendFile "квадраты" (show [(x,x*x) | x >- [0,0.1..2]])
IO является экземпляром класса . Две монадические связывающие функции, методы в классе , используются для составления последовательностей операций ввода - вывода. Функция >> используется там, где результат первой операции не представляет интереса, например, когда он представляет собой (). Операция >>= передает результат первой операции в качестве аргумента второй операции.
(>>=) :: IO a -> (a -> IO b) -> IO b (>>) :: IO a -> IO b -> IO b
Например, программа
main = readFile "input-file" >>= \ s ->
writeFile "output-file" (filter isAscii s) >>
putStr "Фильтрация завершилась успешно\n"
похожа на предыдущий пример, использующий interact, но получает свой ввод из "input-file" и записывает свой вывод в "output-file". Перед завершением программы на стандартный вывод распечатывается сообщение.
Нотация do позволяет программировать в более императивном синтаксическом стиле. Слегка более сложной версией предыдущего примера была бы программа:
main = do
putStr "Файл ввода: "
ifile <- getLine
putStr "Файл вывода: "
ofile <- getLine
s <- readFile ifile
writeFile ofile (filter isAscii s)
putStr "Фильтрация завершилась успешно\n"
Функция return используется для определения результата операции ввода - вывода. Например, getLine определена в терминах getChar, используя return для определения результата:
getLine :: IO String
getLine = do c <- getChar
if c == '\n' then return ""
else do s <- getLine
return (c:s)
Монада ввода - вывода включает простую систему обработки исключений. Любая операция ввода - вывода может вызвать исключение вместо возвращения результата.
Исключения в монаде ввода - вывода представлены значениями типа IOError. Это абстрактный тип: его конструкторы скрыты от пользователя. Библиотека IO определяет функции, которые конструируют и изучают значения IOError . Единственной функцией Prelude, которая создает значение IOError, является userError. Пользовательские значения ошибок включают строку с описанием ошибки.
userError :: String -> IOError
Исключения вызываются и отлавливаются с помощью следующих функций:
ioError :: IOError -> IO a catch :: IO a -> (IOError -> IO a) -> IO a
Функция ioError вызывает исключение; функция catch устанавливает обработчик, который получает любое исключение, вызванное действием, защищенным catch. Исключение отлавливается самым последним обработчиком, установленным catch. Эти обработчики не действуют выборочно: они отлавливают все исключения.
Распространение исключения нужно явно обеспечить в обработчике путем повторного вызова любого нежелательного исключения. Например, в
f = catch g (\e -> if IO.isEOFError e then return [] else ioError e)
функция f возвращает [], когда в g возникает исключение конца файла, иначе исключение передается следующему внешнему обработчику. Функция isEOFError является частью библиотеки IO.
Когда исключение передается за пределы главной программы, система Haskell выводит связанное с ним значение IOError и выходит из программы.
Метод fail экземпляра IO класса (раздел 6.3.6) вызывает userError так:
instance Monad IO where
...bindings for return, (>>=), (>>)
fail s = ioError (userError s)
Исключения, вызванные функциями ввода - вывода в Prelude, описаны в лекции 21.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.