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

readConfig :: String -> IO Config

print

:: Show a => a -> IO ()

-- большая и сложная, но !чистая! функция

algorithm

:: Int -> Config -> Result

Функция readInit читает начальное значение, функция readConfig читает из файла наcтройки, функ-

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

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

algorithm. В этой схеме мы добавили взаимодействие с пользователем лишь в одном месте, вся функция

algorithm построена по правилам мира описаний. Так мы внесли порядок выполнения в программу, сохра-

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

Если у нас будет ещё один “кадр”, ещё одно действие, например как только функция algorithm закончила

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

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

program =

liftA2 algorithm2 readInit

(liftA2 algorithm1 readInit (readConfig ”file”))

>>= print

-- функции с побочными эффектами

readInit

:: IO Int

readConfig :: String -> IO Config

print

:: Show a => a -> IO ()

-- большие и сложные, но !чистые! функции

algorithm1

:: Int -> Config -> Result1

algorithm2

:: Int -> Result1 -> Result2

Теперь у нас два кадра, программа выполняется в два этапа. Каждый из них разделён участками взаимо-

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

строк написаны в мире описаний, исключительно чистыми функциями, которые поднимаются в мир специ-

альных функций с помощью функций liftA2 и стыкуются с помощью операции связывания >>=.

Попробуем тип IO в интерпретаторе. Мы будем пользоваться двумя стандартными функциями getChar и

print

-- читает символ с клавиатуры

getChar :: IO Char

-- выводит значение на экран

print :: IO ()

128 | Глава 8: IO

Функция print возвращает значение единичного типа, завёрнутое в тип IO, поскольку нас интересует не

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

Закодируем два примера из первого раздела. В первом мы читаем один символ и печатаем его дважды:

Prelude> :m Control.Applicative

Prelude Control.Applicative> let res = (\c -> c:c:[]) <$> getChar >>= print

Prelude Control.Applicative> res

q”qq”

Мы сначала вызываем функцию getChar удваиваем результат функцией \c -> c:c:[] и затем выводим

на экран.

Во втором примере мы дважды запрашиваем символ с клавиатуры а затем печатаем их:

Prelude Control.Applicative> let res = liftA2 (\a b -> a:b:[]) getChar getChar >>= print

Prelude Control.Applicative> res

qw”qw”

8.3 Как пишутся программы

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

тельные программы. Программа обозначается специальным именем:

main :: IO ()

Если модуль называется Main или в нём нет директивы module ... where и в модуле есть функция main

:: IO (), то после компиляции будет сделан исполняемый файл. Его можно запускать независимо от ghci.

Просто нажимаем дважды мышкой или вызываем из командной строки.

Напишем программу Hello world. Единственное, что она делает это выводит на экран приветствие:

main :: IO ()

main = print ”Hello World!”

Теперь сохраним эти строчки в файле Hello. hs, перейдём в директорию файла и скомпилируем файл:

ghc --make Hello

Появились объектный и интерфейсный файлы, а также появился третий бинарный файл. Это либо Hello

без расширения (в Linux) или Hello. exe (в Windows). Запустим этот файл:

$ ./Hello

”Hello World!”

Получилось! Это наша первая программа. Теперь напишем программу, которая принимает три символа

с клавиатуры и выводит их в обратном порядке:

import Control.Applicative

f :: Char -> Char -> Char -> String

f a b c = reverse $ [a,b,c]

main :: IO ()

main = print =<< f <$> getChar <*> getChar <*> getChar

Сохраним в файле ReverseIO. hs и скомпилируем:

ghc --make ReverseIO -o rev3

Дополнительным флагом -o мы попросили компилятор чтобы он сохранил исполняемый файл под име-

нем rev3. Теперь запустим в командной строке:

$ ./rev3

qwe

”ewq”

Как пишутся программы | 129

Набираем три символа и нажимаем ввод. И программа переворачивает ответ. Обратите внимание на то,

что с помощью print мы выводим не просто строку на экран, а строку как значение. Поэтому добавляются

двойные кавычки. Для того чтобы выводить строку существует функция putStr. Заменим print на putStr,

перекомпилируем и посмотрим что получится:

$ ghc --make ReverseIOstr -o rev3str

[1 of 1] Compiling Main

( ReverseIOstr.hs, ReverseIOstr.o )

Linking rev3str ...

$ ./rev3str

123

321$

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

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

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

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

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

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

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

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

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