Ответ в типах.
newtype State s a = State {runState :: s -> (a, s)}
Таким образом, состояние, по существу, функция, которая принимает один параметр, «S» (которую мы называем состояние), и возвращает кортеж (значение, состояние). Монада реализована, как показано ниже
instance Monad (State s) where
return a = State $ \s -> (a,s)
(State f) >>= h = State $ \s -> let (a,s') = f s
in (runState h a) s'
Таким образом, у вас есть функция, которая работает на исходном состоянии и выплевывает значение состояний кортежа, подлежащую обработке с помощью следующей функции в композиции.
В настоящее время put
является следующей функцией.
put newState = State $ \s -> ((),newState)
Это по существу устанавливает состояние, которая будет передана к следующей функции в составе и функциям ниже по потоку будет видеть модифицированное состояние.
Фактически, государственная монада полностью чиста (то есть ничего не устанавливается); только то, что передается нисходящим изменениям. Другими словами, государственная монада спасает вас от несанкционированного переноса состояния на чистом языке, таком как Haskell. Другими словами, государственная монада просто предоставляет интерфейс, который скрывает детали потоковой передачи состояния (это то, что вызывается в WikiBooks и, как я полагаю, выучите вам Haskell).
Следующие действия показаны в действии. У вас есть значение, которое устанавливает поле значения таким же, как поле состояния (обратите внимание, что когда я имею в виду установку, я имею в виду вывод, а не переменную). put
получает состояние через переданное ему значение, увеличивает его и устанавливает состояние с этим новым значением.
-- execState :: State s a -> s -> s
let x = get >>= \x -> put (x+10)
execState x 10
Вышеприведенные выходы 20.
Теперь, давайте сделаем следующее.
execState (x >> x) 10
Это даст выход 30. Первый x
устанавливает состояние до 20 с помощью надетой. Это теперь используется вторым x
. В этой точке get
устанавливает, что состояние передало его в поле значений, которое теперь равно 20. Теперь наш put получит это значение, увеличит его на 10 и установит в качестве нового состояния.
Таким образом, у вас есть состояния в чистом контексте. Надеюсь это поможет.