1
{-# LANGUAGE UndecidableInstances #-}
2
-- Search for UndecidableInstances to see why this is needed
4
-----------------------------------------------------------------------------
6
-- Module : Control.Monad.State.Strict
7
-- Copyright : (c) Andy Gill 2001,
8
-- (c) Oregon Graduate Institute of Science and Technology, 2001
9
-- License : BSD-style (see the file libraries/base/LICENSE)
11
-- Maintainer : libraries@haskell.org
12
-- Stability : experimental
13
-- Portability : non-portable (multi-param classes, functional dependencies)
15
-- Strict state monads.
17
-- This module is inspired by the paper
18
-- /Functional Programming with Overloading and
19
-- Higher-Order Polymorphism/,
20
-- Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)
21
-- Advanced School of Functional Programming, 1995.
23
-- See below for examples.
25
-----------------------------------------------------------------------------
27
module Control.Monad.State.Strict (
28
module Control.Monad.State.Class,
42
module Control.Monad.Fix,
43
module Control.Monad.Trans,
49
import Control.Monad.Cont.Class
50
import Control.Monad.Error.Class
51
import Control.Monad.Fix
52
import Control.Monad.Reader.Class
53
import Control.Monad.State.Class
54
import Control.Monad.Trans
55
import Control.Monad.Writer.Class
57
-- ---------------------------------------------------------------------------
58
-- | A parameterizable state monad where /s/ is the type of the state
59
-- to carry and /a/ is the type of the /return value/.
61
newtype State s a = State { runState :: s -> (a, s) }
63
-- |Evaluate this state monad with the given initial state,throwing
64
-- away the final state. Very much like @fst@ composed with
67
evalState :: State s a -- ^The state to evaluate
68
-> s -- ^An initial value
69
-> a -- ^The return value of the state application
70
evalState m s = fst (runState m s)
72
-- |Execute this state and return the new state, throwing away the
73
-- return value. Very much like @snd@ composed with
76
execState :: State s a -- ^The state to evaluate
77
-> s -- ^An initial value
78
-> s -- ^The new state
79
execState m s = snd (runState m s)
81
-- |Map a stateful computation from one (return value, state) pair to
82
-- another. For instance, to convert numberTree from a function that
83
-- returns a tree to a function that returns the sum of the numbered
84
-- tree (see the Examples section for numberTree and sumTree) you may
87
-- > sumNumberedTree :: (Eq a) => Tree a -> State (Table a) Int
88
-- > sumNumberedTree = mapState (\ (t, tab) -> (sumTree t, tab)) . numberTree
90
mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
91
mapState f m = State $ f . runState m
93
-- |Apply this function to this state and return the resulting state.
94
withState :: (s -> s) -> State s a -> State s a
95
withState f m = State $ runState m . f
98
instance Functor (State s) where
99
fmap f m = State $ \s -> case runState m s of
102
instance Monad (State s) where
103
return a = State $ \s -> (a, s)
104
m >>= k = State $ \s -> case runState m s of
105
(a, s') -> runState (k a) s'
107
instance MonadFix (State s) where
108
mfix f = State $ \s -> let (a, s') = runState (f a) s in (a, s')
110
instance MonadState s (State s) where
111
get = State $ \s -> (s, s)
112
put s = State $ \_ -> ((), s)
114
-- ---------------------------------------------------------------------------
115
-- | A parameterizable state monad for encapsulating an inner
118
-- The StateT Monad structure is parameterized over two things:
122
-- * m - The inner monad.
124
-- Here are some examples of use:
126
-- (Parser from ParseLib with Hugs)
128
-- > type Parser a = StateT String [] a
129
-- > ==> StateT (String -> [(a,String)])
131
-- For example, item can be written as:
133
-- > item = do (x:xs) <- get
137
-- > type BoringState s a = StateT s Indentity a
138
-- > ==> StateT (s -> Identity (a,s))
140
-- > type StateWithIO s a = StateT s IO a
141
-- > ==> StateT (s -> IO (a,s))
143
-- > type StateWithErr s a = StateT s Maybe a
144
-- > ==> StateT (s -> Maybe (a,s))
146
newtype StateT s m a = StateT { runStateT :: s -> m (a,s) }
148
-- |Similar to 'evalState'
149
evalStateT :: (Monad m) => StateT s m a -> s -> m a
151
(a, _) <- runStateT m s
154
-- |Similar to 'execState'
155
execStateT :: (Monad m) => StateT s m a -> s -> m s
157
(_, s') <- runStateT m s
160
-- |Similar to 'mapState'
161
mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
162
mapStateT f m = StateT $ f . runStateT m
164
-- |Similar to 'withState'
165
withStateT :: (s -> s) -> StateT s m a -> StateT s m a
166
withStateT f m = StateT $ runStateT m . f
168
instance (Monad m) => Functor (StateT s m) where
169
fmap f m = StateT $ \s -> do
170
(x, s') <- runStateT m s
173
instance (Monad m) => Monad (StateT s m) where
174
return a = StateT $ \s -> return (a, s)
175
m >>= k = StateT $ \s -> do
176
(a, s') <- runStateT m s
178
fail str = StateT $ \_ -> fail str
180
instance (MonadPlus m) => MonadPlus (StateT s m) where
181
mzero = StateT $ \_ -> mzero
182
m `mplus` n = StateT $ \s -> runStateT m s `mplus` runStateT n s
184
instance (MonadFix m) => MonadFix (StateT s m) where
185
mfix f = StateT $ \s -> mfix $ \ ~(a, _) -> runStateT (f a) s
187
instance (Monad m) => MonadState s (StateT s m) where
188
get = StateT $ \s -> return (s, s)
189
put s = StateT $ \_ -> return ((), s)
191
-- ---------------------------------------------------------------------------
192
-- Instances for other mtl transformers
194
instance MonadTrans (StateT s) where
195
lift m = StateT $ \s -> do
199
instance (MonadIO m) => MonadIO (StateT s m) where
200
liftIO = lift . liftIO
202
instance (MonadCont m) => MonadCont (StateT s m) where
203
callCC f = StateT $ \s ->
205
runStateT (f (\a -> StateT $ \s' -> c (a, s'))) s
207
instance (MonadError e m) => MonadError e (StateT s m) where
208
throwError = lift . throwError
209
m `catchError` h = StateT $ \s -> runStateT m s
210
`catchError` \e -> runStateT (h e) s
212
-- Needs UndecidableInstances
213
instance (MonadReader r m) => MonadReader r (StateT s m) where
215
local f m = StateT $ \s -> local f (runStateT m s)
217
-- Needs UndecidableInstances
218
instance (MonadWriter w m) => MonadWriter w (StateT s m) where
220
listen m = StateT $ \s -> do
221
((a, s'), w) <- listen (runStateT m s)
223
pass m = StateT $ \s -> pass $ do
224
((a, f), s') <- runStateT m s
227
-- ---------------------------------------------------------------------------
229
-- A function to increment a counter. Taken from the paper
230
-- /Generalising Monads to Arrows/, John
231
-- Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:
233
-- > tick :: State Int Int
234
-- > tick = do n <- get
238
-- Add one to the given number using the state monad:
240
-- > plusOne :: Int -> Int
241
-- > plusOne n = execState tick n
243
-- A contrived addition example. Works only with positive numbers:
245
-- > plus :: Int -> Int -> Int
246
-- > plus n x = execState (sequence $ replicate n tick) x
248
-- An example from /The Craft of Functional Programming/, Simon
249
-- Thompson (<http://www.cs.kent.ac.uk/people/staff/sjt/>),
250
-- Addison-Wesley 1999: \"Given an arbitrary tree, transform it to a
251
-- tree of integers in which the original elements are replaced by
252
-- natural numbers, starting from 0. The same element has to be
253
-- replaced by the same number at every occurrence, and when we meet
254
-- an as-yet-unvisited element we have to find a \'new\' number to match
257
-- > data Tree a = Nil | Node a (Tree a) (Tree a) deriving (Show, Eq)
258
-- > type Table a = [a]
260
-- > numberTree :: Eq a => Tree a -> State (Table a) (Tree Int)
261
-- > numberTree Nil = return Nil
262
-- > numberTree (Node x t1 t2)
263
-- > = do num <- numberNode x
264
-- > nt1 <- numberTree t1
265
-- > nt2 <- numberTree t2
266
-- > return (Node num nt1 nt2)
268
-- > numberNode :: Eq a => a -> State (Table a) Int
270
-- > = do table <- get
271
-- > (newTable, newPos) <- return (nNode x table)
274
-- > nNode:: (Eq a) => a -> Table a -> (Table a, Int)
276
-- > = case (findIndexInList (== x) table) of
277
-- > Nothing -> (table ++ [x], length table)
278
-- > Just i -> (table, i)
279
-- > findIndexInList :: (a -> Bool) -> [a] -> Maybe Int
280
-- > findIndexInList = findIndexInListHelp 0
281
-- > findIndexInListHelp _ _ [] = Nothing
282
-- > findIndexInListHelp count f (h:t)
285
-- > else findIndexInListHelp (count+1) f t
287
-- numTree applies numberTree with an initial state:
289
-- > numTree :: (Eq a) => Tree a -> Tree Int
290
-- > numTree t = evalState (numberTree t) []
292
-- > testTree = Node "Zero" (Node "One" (Node "Two" Nil Nil) (Node "One" (Node "Zero" Nil Nil) Nil)) Nil
293
-- > numTree testTree => Node 0 (Node 1 (Node 2 Nil Nil) (Node 1 (Node 0 Nil Nil) Nil)) Nil
295
-- sumTree is a little helper function that does not use the State monad:
297
-- > sumTree :: (Num a) => Tree a -> a
299
-- > sumTree (Node e t1 t2) = e + (sumTree t1) + (sumTree t2)