{-# LANGUAGE CPP #-}{-# LANGUAGE FunctionalDependencies #-}{-# LANGUAGE FlexibleInstances #-}{-# LANGUAGE MultiParamTypeClasses #-}{-# LANGUAGE UndecidableInstances #-}-- Search for UndecidableInstances to see why this is needed------------------------------------------------------------------------------- |-- Module : Control.Monad.State.Class-- Copyright : (c) Andy Gill 2001,-- (c) Oregon Graduate Institute of Science and Technology, 2001-- License : BSD-style (see the file LICENSE)---- Maintainer : libraries@haskell.org-- Stability : experimental-- Portability : non-portable (multi-param classes, functional dependencies)---- MonadState class.---- This module is inspired by the paper-- /Functional Programming with Overloading and Higher-Order Polymorphism/,-- Mark P Jones (<http://web.cecs.pdx.edu/~mpj/>)-- Advanced School of Functional Programming, 1995.-----------------------------------------------------------------------------moduleControl.Monad.State.Class(MonadState (..),modify ,modify' ,gets )whereimportControl.Monad.Trans.ContimportControl.Monad.Trans.ErrorimportControl.Monad.Trans.ExceptimportControl.Monad.Trans.IdentityimportControl.Monad.Trans.ListimportControl.Monad.Trans.MaybeimportControl.Monad.Trans.ReaderimportqualifiedControl.Monad.Trans.RWS.LazyasLazyRWS(RWST,get,put,state)importqualifiedControl.Monad.Trans.RWS.StrictasStrictRWS(RWST,get,put,state)importqualifiedControl.Monad.Trans.State.LazyasLazy(StateT,get,put,state)importqualifiedControl.Monad.Trans.State.StrictasStrict(StateT,get,put,state)importControl.Monad.Trans.Writer.LazyasLazyimportControl.Monad.Trans.Writer.StrictasStrictimportControl.Monad.Trans.Class(lift)importControl.MonadimportData.Monoid-- ----------------------------------------------------------------------------- | Minimal definition is either both of @get@ and @put@ or just @state@classMonadm =>MonadState s m |m->swhere-- | Return the state from the internals of the monad.get ::m s get =state (\s ->(s ,s ))-- | Replace the state inside the monad.put ::s ->m ()put s =state (\_->((),s ))-- | Embed a simple state action into the monad.state ::(s ->(a ,s ))->m a state f =dos <-get let~(a ,s' )=f s put s' returna #if __GLASGOW_HASKELL__ >= 707 {-# MINIMALstate|get,put#-}#endif -- | Monadic state transformer.---- Maps an old state to a new state inside a state monad.-- The old state is thrown away.---- > Main> :t modify ((+1) :: Int -> Int)-- > modify (...) :: (MonadState Int a) => a ()---- This says that @modify (+1)@ acts over any-- Monad that is a member of the @MonadState@ class,-- with an @Int@ state.modify::MonadState s m =>(s ->s )->m ()modify f =state (\s ->((),f s ))-- | A variant of 'modify' in which the computation is strict in the-- new state.---- @since 2.2modify'::MonadState s m =>(s ->s )->m ()modify' f =dos' <-get put $!f s' -- | Gets specific component of the state, using a projection function-- supplied.gets::MonadState s m =>(s ->a )->m a gets f =dos <-get return(f s )instanceMonadm =>MonadState s (Lazy.StateTs m )whereget =Lazy.getput =Lazy.putstate =Lazy.stateinstanceMonadm =>MonadState s (Strict.StateTs m )whereget =Strict.getput =Strict.putstate =Strict.stateinstance(Monadm ,Monoidw )=>MonadState s (LazyRWS.RWSTr w s m )whereget =LazyRWS.getput =LazyRWS.putstate =LazyRWS.stateinstance(Monadm ,Monoidw )=>MonadState s (StrictRWS.RWSTr w s m )whereget =StrictRWS.getput =StrictRWS.putstate =StrictRWS.state-- ----------------------------------------------------------------------------- Instances for other mtl transformers---- All of these instances need UndecidableInstances,-- because they do not satisfy the coverage condition.instanceMonadState s m =>MonadState s (ContTr m )whereget =liftget put =lift.put state =lift.state instance(Errore ,MonadState s m )=>MonadState s (ErrorTe m )whereget =liftget put =lift.put state =lift.state -- | @since 2.2instanceMonadState s m =>MonadState s (ExceptTe m )whereget =liftget put =lift.put state =lift.state instanceMonadState s m =>MonadState s (IdentityTm )whereget =liftget put =lift.put state =lift.state instanceMonadState s m =>MonadState s (ListTm )whereget =liftget put =lift.put state =lift.state instanceMonadState s m =>MonadState s (MaybeTm )whereget =liftget put =lift.put state =lift.state instanceMonadState s m =>MonadState s (ReaderTr m )whereget =liftget put =lift.put state =lift.state instance(Monoidw ,MonadState s m )=>MonadState s (Lazy.WriterTw m )whereget =liftget put =lift.put state =lift.state instance(Monoidw ,MonadState s m )=>MonadState s (Strict.WriterTw m )whereget =liftget put =lift.put state =lift.state