Читаем Учебник по Haskell полностью

Видно, что после вывода не произошёл перенос каретки, терминал приглашает нас к вводу команды сразу

за ответом, если перенос нужен, можно воспользоваться функцией putStrLn. Обратите внимание на то, что

кроме бинарного файла появились ещё два файла с расширениями . hi и . o. Первый файл называется ин-

терфейсным он описывает какие в модуле определения, а второй файл называется объектным. Он содержит

скомпилированный код модуля.

Стоит отметить команду runhaskell. Она запускает программу без создания дополнительных файлов.

Но в этом случае выполнение программы будет происходить медленнее.

8.4 Типичные задачи IO

Вывод на экран

Нам уже встретилось несколько функций вывода на экран. Это функции: print (вывод значения из эк-

земпляра класса Show), putStr (вывод строки) и putStrLn (вывод строки с переносом). Каждый раз когда мы

набираем какое-нибудь выражение в строке интерпретатора и нажимаем Enter, интерпретатор применяет к

выражению функцию print и мы видим его на экране.

Из простейших функций вывода на экран осталось не рассмотренной лишь функция putChar, но я думаю

вы без труда догадаетесь по типу и имени чем она занимается:

putChar :: Char -> IO ()

Функции вывода на экран также можно вызывать в интерпретаторе:

Prelude> putStr ”Hello” >> putChar ’ ’ >> putStrLn ”World!”

Hello World!

Обратите внимание на применение постоянной функции для монад >> . В этом выражении нас интересует

не результат, а те побочные эффекты, которые выполняются при композиции специальных функций. Также

мы пользовались функцией >> в сочетании с монадой Writer для накопления результата.

Ввод пользователя

Мы уже умеем принимать от пользователя буквы. Это делается функцией getChar. Функцией getLine мы

можем прочитать целую строчку. Строка читается до тех пор пока мы не нажмём Enter.

Prelude> fmap reverse $ getLine

Hello-hello!

”!olleh-olleH”

Есть ещё одна функция для чтения строк, она называется getContents. Основное отличие от getLine

заключается в том, что содержание не читается сразу, а откладывается на потом, когда содержание дей-

ствительно понадобится. Это ленивый ввод. Для задачи чтения символов с терминала эта функция может

показаться странной. Но часто в символы вводятся не вручную, а передаются из другого файла. Например

если мы направим на ввод данные из-какого-нибудь большого-большого файла, файл не будет читаться сра-

зу, и память не будет заполнена не нужным пока содержанием. Вместо этого программа отложит считывание

на потом и будет заниматься им лишь тогда, когда оно понадобится в вычислениях. Это может существенно

снизить расход памяти. Мы читаем файл в 2Гб моментально (мы делаем вид, что читаем его). А на самом

деле сохраняем себе задачу на будущее: читать ввод, когда придёт пора.

130 | Глава 8: IO

Чтение и запись файлов

Для чтения и записи файлов есть три простые функции:

type FilePath = String

-- чтение файла

readFile

:: FilePath -> IO String

-- запись строки в файл

writeFile

:: FilePath -> String -> IO ()

-- добавление строки в конеци файла

appendFile

:: FilePath -> String -> IO ()

Напишем программу, которая сначала запрашивает путь к файлу. Затем показывает его содержание. За-

тем запрашивает ввод строки из терминала. А после этого добавляет текст в конец файла.

main = msg1 >> getLine >>= read >>= append

where read

file = readFile file >>= putStrLn >> return file

append file = msg2 >> getLine >>= appendFile file

msg1

= putStr ”input file: ”

msg2

= putStr ”input text: ”

В самом левом вызове getLine мы читаем имя файла, затем оно используется в локальной функции

read. Там мы читаем содержание файла (readLine), выводим его на экран (putStrLn), и в самом конце мы

возвращаем из функции имя файла. Оно нам понадобится в следующей части программы, в которой мы

будем читать новые записи и добавлять их в файл. Новая запись читается функцией getLine в локальной

функции append.

Сохраним в модуле File. hs и посмотрим, что у нас получилось. Перед этим создадим в текущей дирек-

тории тестовый пустой файл под именем test. В него мы будем добавлять новые записи.

*Prelude> :l File

[1 of 1] Compiling File

( File. hs, interpreted )

Ok, modules loaded: File.

*File> main

input file: test

input text: Hello!

*File> main

input file: test

Hello!

input text: Hi)

*File> main

input file: test

Hello!Hi)

В самом начале наш файл пуст, поэтому сначала мы видим пустую строчку вместо содержания, но потом

мы начинаем добавлять в него новые записи.

Ленивое и энергичное чтение файлов

С чтением файлов связана одна тонкость. Функция readFile читает содержимое файла в ленивом стиле.

Подробнее о ленивой стратегии вычислений мы поговорим в следующей главе. По ка отметим, что readFile

не читает следующую порцию файла до тех пор пока она не понадобится в программе. Иногда это очень удоб-

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных