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

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

времени. И на остальные задачи у нас не хватит сил или мы можем потратить много времени на решение

задачи, которая совсем не нужна для итогового решения. Также как и в вычислениях по значению, мы можем

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

малая часть.

Ещё один плюс решения сверху вниз состоит в экономии усилий. Мы можем написать всю программу в

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

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

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

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

мы можем начать заполнять дыры и детализировать отдельные выражения. Так мы будем детализировать-

детализировать пока не придём к первоначальному решению. Далее если у нас останется время мы можем

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

пов. Часто такую стратегию разработки называют разработкой через прототипы (developing by prototyping).

При этом процесс написания приложения можно представить как процесс сходимости, приближения к преде-

лу. У нас есть серия промежуточных решений или прототипов, которые с каждым шагом всё точнее и точнее

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

исходит естественно, в ходе детализации, мы можем распределить нагрузку, распределив разные undefined

между участниками проекта.

Слово undefined будет встречаться очень часто, буквально в каждом значении. Оно очень длинное, и

часто писать его будет слишком утомительно. Определим удобный синоним. Я обычно использую un или

lol (что-нибудь краткое и удобное для автоматического поиска):

un :: a

un = undefined

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

Назовём её play. Это функция взаимодействия с пользователем она ведёт диалог, поэтому её тип будет IO

():

play :: IO ()

play = un

Итак у нас появилась корневая функция. Что мы будем в ней делать? Для начала мы поприветствуем игро-

ка (функция greetings). Затем предложим ему начать игру (функция setup), после чего запустим цикл игры

(функция gameLoop). Приветствие это просто надпись на экране, поэтому тип у него будет IO (). Предложе-

ние игры вернёт стартовую позицию для игры, поэтому тип будет IO Game. Цикл игры принимает состояние

и продолжает диалог. В типах это выражается так:

play :: IO ()

play = greetings >> setup >>= gameLoop

greetings :: IO ()

greetings = un

setup :: IO Game

setup = un

gameLoop :: Game -> IO ()

gameLoop = un

Сохраним эти определения в модуле Loop и загрузим модуль с программой в интерпретатор:

Prelude> :l Loop

[1 of 2] Compiling Game

( Game. hs, interpreted )

[2 of 2] Compiling Loop

( Loop. hs, interpreted )

Ok, modules loaded: Game, Loop.

*Loop>

Модуль загрузился. Он потянул за собой модуль Game, потому что мы воспользовались типом Move из

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

У нас три варианта дальнейшей детализации это функции greetings, setup и gameLoop. Мы пока пропу-

стим greetings там мы напишем какое-нибудь приветствие и сообщим игроку куда он попал и как ходить.

204 | Глава 13: Поиграем

В функции setup нам нужно начать первую игру. Для начала игры нам нужно узнать её сложность, на

сколько ходов перемешивать позицию. Это значит, что нам нужно спросить у игрока целое число. Мы спро-

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

попросим его повторить ввод. Функция readInt :: String -> Maybe Int распознаёт число. Она возвращает

целое число завёрнутое в Maybe, потому что строка может оказаться не числом. Затем это число мы исполь-

зуем в функции shuffle (перемешать), которая будет возвращать позицию, которая перемешана с заданной

глубиной.

-- в модуль Loop

setup :: IO Game

setup = putStrLn ”Начнём новую игру?” >>

putStrLn ”Укажите сложность (положительное целое число): ” >>

getLine >>= maybe setup shuffle . readInt

readInt :: String -> Maybe Int

readInt = un

-- в модуль Game:

shuffle :: Int -> IO Game

shuffle = un

Функция shuffle возвращает состояние игры Game, которое завёрнуто в IO. Оно завёрнуто в IO, потому

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

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

в недрах функции shuffle мы воспользуемся newStdGen, которая и потянет за собой тип IO.

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

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

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

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

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

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

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

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

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