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

Для начала напишем очень простую программу, которая открывает файл с именем girlfriend.txt и печатает его на терминале. В этом файле записаны слова лучшего хита Авриль Лавин, «Girlfriend». Вот содержимое girlfriend.txt:

>Эй! Ты! Эй! Ты!

>Мне не нравится твоя подружка!

>Однозначно! Однозначно!

>Думаю, тебе нужна другая!

Программа:

>import System.IO


>main = do

>   handle <– openFile "girlfriend.txt" ReadMode

>   contents <– hGetContents handle

>   putStr contents

>    hClose handle

Скомпилировав и запустив её, получаем ожидаемый результат:

>Эй! Ты! Эй! Ты!

>Мне не нравится твоя подружка!

>Однозначно! Однозначно!

>Думаю, тебе нужна другая!

Посмотрим, что у нас тут? Первая строка – это просто четыре восклицания: они привлекают наше внимание. Во второй строке Авриль сообщает вам, что ей не нравится ваша подружка. Третья строка подчёркивает, что неприятие это категорическое. Ну а четвёртая предписывает подружиться с кем-нибудь получше.

А теперь пройдёмся по каждой строке кода. Наша программа – это несколько действий ввода-вывода, «склеенных» с помощью блока >do. В первой строке блока >do мы использовали новую функцию, >openFile. Вот её сигнатура: >openFile :: FilePath –> IOMode –> IO Handle. Если попробовать это прочитать, получится следующее: «Функция >openFile принимает путь к файлу и режим открытия файла (>IOMode) и возвращает действие ввода-вывода, которое откроет файл, получит дескриптор файла и заключит его в результат».

Тип >FilePath – это просто синоним для типа >String; он определён так:

>type FilePath = String

Тип >IOMode определён так:

>data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode

Этот тип содержит перечисление режимов открытия файла, так же как наш тип содержал перечисление дней недели. Очень просто! Обратите внимание, что этот тип – >IOMode; не путайте его с >IO Mode. Тип >IO Mode может быть типом действия ввода-вывода, которое возвращает результат типа >Mode, но тип >IOMode – это просто перечисление.

В конце концов функция вернёт действие ввода-вывода, которое откроет указанный файл в указанном режиме. Если мы привяжем это действие к имени, то получим дескриптор файла >(Handle). Значение типа >Handle описывает, где находится наш файл. Мы будем использовать дескриптор для того, чтобы знать, из какого файла читать. Было бы глупо открыть файл и не связать дескриптор файла с именем, потому что с ним потом ничего нельзя будет сделать! В нашем случае мы связали дескриптор с идентификатором >handle.

На следующей строке мы видим функцию >hGetContents. Она принимает значение типа >Handle; таким образом, она знает, с каким файлом работать, и возвращает значение типа