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

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

louder и quieter. Так мы не сможем выйти за пределы заданного диапазона.

Возможные события:

108 | Глава 7: Функторы и монады: примеры

data User = Button | Quieter | Louder

deriving (Show)

Пользователь может либо нажать на кнопку вкл/выкл или повернуть реле громкости влево, чтобы при-

глушить звук (Quieter) или вправо, чтобы сделать погромче (Louder). Будем считать, что колонки всегда

включены в розетку.

Составим функцию переходов:

speaker :: User -> FSM Speaker

speaker = fsm $ trans

where trans Button

(Sleep, n) = (Work, n)

trans Button

(Work,

n) = (Sleep, n)

trans Louder

(s,

n) = (s, louder n)

trans Quieter

(s,

n) = (s, quieter n)

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

включении они будут работать на той же громкости. Реле можно крутить и в состоянии Sleep. Посмотрим

на типичную сессию работы колонок:

*FSM> let res = mapM speaker [Button, Louder, Quieter, Quieter, Button]

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

ключаем. Посмотрим что получилось:

*FSM> runState res (Sleep, Level 2)

([(Sleep, Level 2),(Work, Level 2),(Work, Level 3),(Work, Level 2),

(Work, Level 1)],(Sleep, Level 1))

*FSM> runState res (Sleep, Level 0)

([(Sleep, Level 0),(Work, Level 0),(Work, Level 1),(Work, Level 0),

(Work, Level 0)],(Sleep, Level 0))

Смотрите, изменив начальное значение, мы изменили весь список значений. Обратите внимание на то,

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

установленный предел.

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

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

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

с нормальным уровнем звука. При включении колонок нас оглушил шквал звука. Чтобы этого избежать мы

решили воспользоваться другими колонками.

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

только если колонки включены.

safeSpeaker :: User -> FSM Speaker

safeSpeaker = fsm $ trans

where trans Button

(Sleep, _) = (Work,

Level 0)

trans Button

(Work,

_) = (Sleep, Level 0)

trans Quieter (Work,

n) = (Work,

quieter n)

trans Louder

(Work,

n) = (Work,

louder n)

trans _

(Sleep, n) = (Sleep, n)

При нажатии на кнопку вкл/выкл уровень громкости выводится в положение 0. Колонки реагируют на

запросы изменения уровня громкости только в состоянии Work. Посмотрим как работают наши новые колон-

ки:

*FSM> let res = mapM safeSpeaker [Button, Louder, Quieter, Button, Louder]

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

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

громкости 10:

*FSM> runState res (Sleep, Level 10)

([(Sleep, Level 10),(Work, Level 0),(Work, Level 1),(Work, Level 0),

(Sleep, Level 0)],(Sleep, Level 0))

Конечные автоматы | 109

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

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

ляем её и выключаем. Попытка изменить громкость выключенных колонок не проходит. Это видно по по-

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

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

смотрим, что случится дальше:

*FSM> runState res (Work, Level 10)

([(Work, Level 10),(Sleep, Level 0),(Sleep, Level 0),(Sleep, Level 0),

(Work, Level 0)],(Work, Level 1))

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

7.3 Отложенное вычисление выражений

В этом примере мы будем выполнять арифметические операции на целых числах. Мы будем их скла-

дывать, вычитать и умножать. Но вместо того, чтобы сразу вычислять выражения мы будем составлять их

описание. Мы будем кодировать операции конструкторами.

data Exp

= Var String

| Lit Int

| Neg Exp

| Add Exp Exp

| Mul Exp Exp

deriving (Show, Eq)

У нас есть тип Exp, который может быть либо переменной Var с данным строчным именем, либо целочис-

ленной константой Lit, либо одной из трёх операций: вычитанием (Neg), сложением (Add) или умножением

(Mul).

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

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

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

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

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

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

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

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

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