52700.fb2 Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 115

Учебник по Haskell - читать онлайн бесплатно полную версию книги . Страница 115

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

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

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