Control.Monad.Trans.State.Strict
| Copyright | (c) Andy Gill 2001, (c) Oregon Graduate Institute of Science and Technology, 2001 |
|---|---|
| License | BSD-style (see the file LICENSE) |
| Maintainer | ross@soi.city.ac.uk |
| Stability | experimental |
| Portability | portable |
| Safe Haskell | Safe |
| Language | Haskell98 |
Содержание
Описание
Жесткие монады состояния, передающие изменяемое состояние через вычисление. Примеры см. ниже.
Некоторые вычисления могут не требовать полной мощи трансформаторов состояния:
- Для чтения состояния без изменения, см. Control.Monad.Trans.Reader.
- Для накопления значения без его использования по ходу, см. Control.Monad.Trans.Writer.
В этой версии, последовательность вычислений является жёсткой (но вычисления не жёсткие относительно состояния, пока вы его не принудите с помощью seq или аналогичным образом). Для ленивой версии с тем же интерфейсом, см. Control.Monad.Trans.State.Lazy.
Монад состояния
type State s = StateT s Identity Источник
Монад состояния, параметризованная типом s состояния.
Функция return оставляет состояние неизменным, в то время как >>= использует конечное состояние первого вычисления в качестве начального состояния второго.
Аргументы
| :: Monad m | |
| => (s -> (a, s)) | чистая трансформатор состояния |
| -> StateT s m a | эквивалентное вычисление с передачей состояния |
Построение вычисления монады состояния из функции. (Обратное к runState.)
Аргументы
| :: State s a | вычисление с передачей состояния для выполнения |
| -> s | начальное состояние |
| -> (a, s) | возвращаемое значение и конечное состояние |
Распаковка вычисления монады состояния как функции. (Обратное к state.)
Аргументы
| :: State s a | вычисление с передачей состояния для выполнения |
| -> s | начальное значение |
| -> a | возвращаемое значение вычисления состояния |
Выполнение вычисления состояния с заданным начальным состоянием и возвращение конечного значения, отбрасывая конечное состояние.
Аргументы
| :: State s a | вычисление с передачей состояния для выполнения |
| -> s | начальное значение |
| -> s | конечное состояние |
Выполнение вычисления состояния с заданным начальным состоянием и возвращение конечного состояния, отбрасывая конечное значение.
mapState :: ((a, s) -> (b, s)) -> State s a -> State s b Источник
Применение функции к возвращаемому значению и конечному состоянию вычисления.
withState :: (s -> s) -> State s a -> State s a Источник
withState f m выполняет действие m над состоянием, изменённым путём применения f.
Трансформатор монады StateT
Трансформатор монады состояния, параметризованный:
-
s- Состояние. -
m- Внутренняя монада.
Функция return оставляет состояние неизменным, в то время как >>= использует конечное состояние первого вычисления в качестве начального состояния второго.
Примеры использования
evalStateT :: Monad m => StateT s m a -> s -> m a Источник
Выполнение вычисления состояния с заданным начальным состоянием и возвращение конечного значения, отбрасывая конечное состояние.
evalStateTm s =liftMfst(runStateTm s)
execStateT :: Monad m => StateT s m a -> s -> m s Источник
Выполнение вычисления состояния с заданным начальным состоянием и возвращение конечного состояния, отбрасывая конечное значение.
execStateTm s =liftMsnd(runStateTm s)
mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b Источник
Применение функции к возвращаемому значению и конечному состоянию вычисления.
withStateT :: (s -> s) -> StateT s m a -> StateT s m a Source
withStateT f m выполняет действие m над состоянием, изменённым путём применения f.
withStateTf m =modifyf >> m
Операции со состоянием
get :: Monad m => StateT s m s Source
Получение текущего значения состояния в монаде.
put :: Monad m => s -> StateT s m () Source
put s устанавливает состояние в монаде на s.
modify :: Monad m => (s -> s) -> StateT s m () Source
modify f — это действие, которое обновляет состояние результатом применения f к текущему состоянию.
modify' :: Monad m => (s -> s) -> StateT s m () Source
Вариант modify, в котором вычисление строго в новом состоянии.
gets :: Monad m => (s -> a) -> StateT s m a Source
Получение определённого компонента состояния с помощью предоставленной функции проекции.
Поднятие других операций
liftCallCC :: CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b Source
Единое поднятие операции callCC в новую монаду. В этой версии при входе в продолжение происходит откат к исходному состоянию.
liftCallCC' :: CallCC m (a, s) (b, s) -> CallCC (StateT s m) a b Source
Поднятие операции callCC в новую монаду в текущем контексте. Эта версия использует текущее состояние при входе в продолжение. Она не удовлетворяет законам трансформатора монады.
liftCatch :: Catch e m (a, s) -> Catch e (StateT s m) a Source
Поднять операцию catchE в новую монаду.
liftListen :: Monad m => Listen w m (a, s) -> Listen w (StateT s m) a Source
Поднять операцию listen в новую монаду.
liftPass :: Monad m => Pass w m (a, s) -> Pass w (StateT s m) a Source
Поднять операцию pass в новую монаду.
Примеры
Монады состояния
Парсер из ParseLib с Hugs:
type Parser a = StateT String [] a ==> StateT (String -> [(a,String)])
Например, item можно записать как:
item = do (x:xs) <- get
put xs
return x
type BoringState s a = StateT s Identity a
==> StateT (s -> Identity (a,s))
type StateWithIO s a = StateT s IO a
==> StateT (s -> IO (a,s))
type StateWithErr s a = StateT s Maybe a
==> StateT (s -> Maybe (a,s))
Подсчёт
Функция для инкрементирования счётчика. Взято из статьи «Обобщение монад на стрелки», Джон Хьюз (http://www.cse.chalmers.se/~rjmh/), ноябрь 1998 г.:
tick :: State Int Int
tick = do n <- get
put (n+1)
return n
Добавление единицы к заданному числу с использованием монады состояния:
plusOne :: Int -> Int plusOne n = execState tick n
Искусственный пример сложения. Работает только с положительными числами:
plus :: Int -> Int -> Int plus n x = execState (sequence $ replicate n tick) x
Разметка деревьев
Пример из «Ремесло функционального программирования», Саймон Томпсон (http://www.cs.kent.ac.uk/people/staff/sjt/), Addison-Wesley 1999: «Дано произвольное дерево, преобразуйте его в дерево целых чисел, в котором исходные элементы заменяются натуральными числами, начиная с 0. Один и тот же элемент должен заменяться одним и тем же числом при каждом появлении, и когда мы встречаем ещё не посещённый элемент, мы должны найти «новое» число для его сопоставления с ним»:
data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Eq) type Table a = [a]
numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)
numberTree Nil = return Nil
numberTree (Node x t1 t2) = do
num <- numberNode x
nt1 <- numberTree t1
nt2 <- numberTree t2
return (Node num nt1 nt2)
where
numberNode :: Eq a => a -> State (Table a) Int
numberNode x = do
table <- get
case elemIndex x table of
Nothing -> do
put (table ++ [x])
return (length table)
Just i -> return i
numTree применяет numberTree с начальным состоянием:
numTree :: (Eq a) => Tree a -> Tree Int numTree t = evalState (numberTree t) []
testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil
© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/transformers-0.4.2.0/Control-Monad-Trans-State-Strict.html