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

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

на основе прочитанного текста. При этом в памяти будет храниться лишь малая часть файла. Но иногда

это свойство мешает. Рассмотрим такую задачу: перевернуть текст в файле под именем ”test”. Мы должны

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

написать эту программу так:

module Main where

main :: IO ()

main = inFile reverse ”test”

inFile :: (String -> String) -> FilePath -> IO ()

inFile fun file = writeFile file . fun =<< readFile file

Типичные задачи IO | 131

Функция inFile обновляет текст файла с помощью некоторого преобразование. Но если мы запустим эту

программу:

*Main> main

*** Exception: test: openFile: resource busy (file is locked)

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

ция readFile заняла файл, за счёт чтения по кусочкам. Для решения этой проблемы необходимо воспользо-

ваться энергичной версией функции readFile, она будет читать файл целиком. Эта функция живёт в модуле

System.IO.Strict:

import qualified System.IO.Strict as StrictIO

inFile :: (String -> String) -> FilePath -> IO ()

inFile fun file = writeFile file . fun =<< StrictIO. readFile file

Функция main осталась прежней. Теперь наша программа спокойно переворачивает текст файла.

Аргументы программы

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

программы, они работали в интерактивном режиме, но чаще всего программы принимают какие-нибудь

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

System.Environment.

Узнать, что передаётся в программу можно функцией getArgs :: IO [String]. Она возвращает список

строк. Это те строки, что мы написали за именем программы через пробел при вызове в терминале. Напишем

простую программу, которая распечатывает свои аргументы по порядку, в виде пронумерованного списка.

module Main where

import System.Environment

main = getArgs >>= mapM_ putStrLn . zipWith f [1 .. ]

where f n a = show n ++ ”: ” ++ a

В локальной функции f мы присоединяем к строке номер через двоеточие. Функцией mapM_ мы пробегаем

по списку строк, отображая их с помощью функции putStrLn. Обратите внимание на краткость программы,

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

затем выводит их на экран.

Скомпилируем программу в интерпретаторе и вызовем её.

*Main> :! ghc --make Args

[1 of 1] Compiling Main

( Args. hs, Args. o )

Linking Args ...

*Main> :! ./Args hey hey hey 23 54 ”qwe qwe qwe” fin

1: hey

2: hey

3: hey

4: 23

5: 54

6: qwe qwe qwe

7: fin

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

С помощью функции getProgName можно узнать имя программы. Создадим программу, которая здоро-

вается при вызове. И отвечает в зависимости от настроения программы. Настроение задаётся аргументом

программы.

module Main where

import Control.Applicative

import System.Environment

main = putStrLn =<< reply <$> getProgName <*> getArgs

132 | Глава 8: IO

reply :: String -> [String] -> String

reply name (x:_) = hi name ++ case x of

”happy”

-> ”What a lovely day. What’s up?”

”sad”

-> ”Ooohh. Have you got some news for me?”

”neutral”

-> ”How are you?”

reply name _

= reply name [”neutral”]

hi :: String -> String

hi name = ”Hi! My name is ” ++ name ++ ”.\n”

В функции reply мы составляем реплику программы. Она зависит от имени программы и поступающих

на вход аргументов. Посмотрим, что у нас получилось:

*Main> :! ghc --make HowAreYou.hs -o ninja

[1 of 1] Compiling Main

( HowAreYou. hs, HowAreYou. o )

Linking ninja ...

*Main> :! ./ninja happy

Hi! My name is ninja.

What a lovely day. What’s up?

*Main> :! ./ninja sad

Hi! My name is ninja.

Ooohh. Have you got some news for me?

Вызов других программ

Мы можем вызвать любую программу из нашей программы. Это делается с помощью функции system,

которая живёт в модуле System.

system :: String -> IO ExitCode

Она принимает строку и запускает её в терминале. Так же как мы делали это с помощью приставки :! в

интерпретаторе. Значение типа ExitCode говорит о результате выполнения строки. Он может быть успешным,

тогда функция вернёт ExitSuccess и закончиться ошибкой, тогда мы сможем узнать код ошибки по значению

ExitFailure Int.

Случайные значения

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

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

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

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

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

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

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

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

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