52700.fb2
Прибавим два списка и получим сумму:
*Random> let res = fmap sum $ zipWithM addRandom2 [1.. 3] [11 .. 13]
*Random> runState res 0.5
(43.060125804029965,0.969511377766409)
*Random> runState res 0.7
(39.86034841613788,0.26599261421101517)
Функция zipWithM является аналогом функции zipWith. Она устроена также как и функция mapM, сначала
применяется обычная функция zipWith, а затем функция sequence.
С помощью типа Random мы можем определить функцию подбрасывания монетки:
Случайные числа | 107
data Coin = Heads | Tails
deriving (Show)
dropCoin :: Random Coin
dropCoin = fmap drop’ next
where drop’ x
| x < 0.5
= Heads
| otherwise = Tails
У монетки две стороны орёл (Heads) и решка (Tails). Поскольку шансы на выпадание той или иной
стороны равны, мы для определения стороны разделяем интервал от 0 до 1 в равных пропорциях.
Подбросим монетку пять раз:
*Random> let res = sequence $ replicate 5 dropCoin
Функция replicate n a составляет список из n повторяющихся элементов a. Посмотрим что у нас полу-
чилось:
*Random> runState res 0.4
([Heads, Heads, Heads, Heads, Tails],0.5184926967068364)
*Random> runState res 0.5
([Tails, Tails, Heads, Tails, Tails],0.6226652135290891)
7.2 Конечные автоматы
С помощью монады State можно описывать конечные автоматы (finite-state machine). Конечный автомат
находится в каком-то начальном состоянии. Он принимает на вход ленту событий. Одно событие происходит
за другим. На каждое событие автомат реагирует переходом из одного состояния в другое.
type FSM s = State s s
fsm :: (ev -> s -> s) -> (ev -> FSM s)
fsm transition = \e -> State $ \s -> (s, transition e s)
Функция fsm принимает функцию переходов состояний transition и возвращает функцию, которая при-
нимает состояние и возвращает конечный автомат. В качестве значения конечный автомат FSM будет возвра-
щать текущее состояние.
С помощью конечных автоматов можно описывать различные устройства. Лентой событий будет ввод
пользователя (нажатие на кнопки, включение/выключение питания).
Приведём простой пример. Рассмотрим колонки, у них есть розетка, кнопка вкл/выкл и регулятор гром-
кости. Возможные состояния:
type Speaker = (SpeakerState, Level)
data SpeakerState = Sleep | Work
deriving (Show)
data Level
= Level Int
deriving (Show)
Тип колонок складывается из двух значений: состояния и уровня громкости. Колонки могут быть вы-