и 
>push уже являются вычислениями с состоянием, легко обернуть их в обёртку 
>State:
>import Control.Monad.State
>pop :: State Stack Int
>pop = state $ \(x:xs) –> (x, xs)
>push :: Int –> State Stack ()
>push a = state $ \xs –> ((), a:xs)
Обратите внимание, как мы задействовали функцию >state, чтобы обернуть функцию в конструктор >newtype State, не прибегая к использованию конструктора значения >State напрямую.
Функция >pop – уже вычисление с состоянием, а функция >push принимает значение типа >Int и возвращает вычисление с состоянием. Теперь мы можем переписать наш предыдущий пример проталкивания числа >3 в стек и выталкивания двух чисел подобным образом:
>import Control.Monad.State
>stackManip :: State Stack Int
>stackManip = do
>   push 3
>   a <– pop
>   pop
Видите, как мы «склеили» проталкивание и два выталкивания в одно вычисление с состоянием? Разворачивая его из обёртки >newtype, мы получаем функцию, которой можем предоставить некое исходное состояние:
>ghci> runState stackManip [5,8,2,1]
>(5,[8,2,1])
Нам не требовалось привязывать второй вызов функции >pop к образцу >a, потому что мы вовсе не использовали этот образец. Значит, это можно было записать вот так:
>stackManip :: State Stack Int
>stackManip = do
>   push 3
>   pop
>   pop
Очень круто! Но что если мы хотим сделать что-нибудь посложнее? Скажем, вытолкнуть из стека одно число, и если это число равно >5, просто протолкнуть его обратно в стек и остановиться. Но если число не равно >5, вместо этого протолкнуть обратно >3 и >8. Вот он код:
>stackStuff :: State Stack ()
>stackStuff = do
>   a <– pop
>   if a == 5
>      then push 5
>      else do
>         push 3
>         push 8
Довольно простое решение. Давайте выполним этот код с исходным стеком:
>ghci> runState stackStuff [9,0,2,1,0] ((),[8,3,0,2,1,0])
Вспомните, что выражения >do возвращают в результате монадические значения, и при использовании монады >State одно выражение >do является также функцией с состоянием. Поскольку функции >stackManip и >stackStuff являются обычными вычислениями с состоянием, мы можем «склеивать» их вместе, чтобы производить дальнейшие вычисления с состоянием:
>moreStack :: State Stack ()
>moreStack = do
>   a <– stackManip
>   if a == 100
>      then stackStuff
>      else return ()
Если результат функции >stackManip при использовании текущего стека равен >100, мы вызываем функцию >stackStuff; в противном случае ничего не делаем. Вызов >return>() просто сохраняет состояние как есть и ничего не делает.