@@ -0,0 +1,146 @@
1+{-# LANGUAGE MultiParamTypeClasses #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE DataKinds #-}
7+{-# LANGUAGE ConstraintKinds #-}
8+{-# LANGUAGE TypeOperators #-}
9+{-# LANGUAGE FunctionalDependencies #-}
10+{-# LANGUAGE ScopedTypeVariables #-}
11+{-# LANGUAGE RankNTypes #-}
12+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
13+module Control.Monad.Ether.State
36+import Data.Proxy (Proxy(Proxy))
37+import Control.Monad.Trans (lift)
39+import Control.Monad.Trans.Ether.State
42+import qualified Control.Monad.Trans.Cont as Trans (ContT)
43+import qualified Control.Monad.Trans.Except as Trans (ExceptT)
44+import qualified Control.Monad.Trans.Identity as Trans (IdentityT)
45+import qualified Control.Monad.Trans.List as Trans (ListT)
46+import qualified Control.Monad.Trans.Maybe as Trans (MaybeT)
47+import qualified Control.Monad.Trans.Reader as Trans (ReaderT)
48+import qualified Control.Monad.Trans.State.Lazy as Trans.Lazy (StateT)
49+import qualified Control.Monad.Trans.State.Strict as Trans.Strict (StateT)
50+import qualified Control.Monad.Trans.Writer.Lazy as Trans.Lazy (WriterT)
51+import qualified Control.Monad.Trans.Writer.Strict as Trans.Strict (WriterT)
53+class Monad m => MonadEtherState tag s m | m tag -> s where
55+ {-# MINIMAL etherState | etherGet, etherPut #-}
57+ etherGet :: proxy tag -> m s
58+ etherGet proxy = etherState proxy (\s -> (s, s))
60+ etherPut :: proxy tag -> s -> m ()
61+ etherPut proxy s = etherState proxy (\_ -> ((), s))
63+ etherState :: proxy tag -> (s -> (a, s)) -> m a
64+ etherState proxy f = do
70+etherGets :: MonadEtherState tag s m => proxy tag -> (s -> a) -> m a
71+etherGets proxy f = fmap f (etherGet proxy)
73+type MonadState' s = MonadEtherState s s
75+get' :: forall m s . MonadState' s m => m s
76+get' = etherGet (Proxy :: Proxy s)
78+gets' :: forall m s a . MonadState' s m => (s -> a) -> m a
79+gets' = etherGets (Proxy :: Proxy s)
81+put' :: forall m s . MonadState' s m => s -> m ()
82+put' = etherPut (Proxy :: Proxy s)
84+state' :: forall m s a . MonadState' s m => (s -> (a, s)) -> m a
85+state' = etherState (Proxy :: Proxy s)
87+instance {-# OVERLAPPING #-} Monad m => MonadEtherState tag s (EtherStateT tag s m) where
88+ etherGet proxy = etherStateT proxy (\s -> return (s, s))
89+ etherPut proxy s = etherStateT proxy (\_ -> return ((), s))
91+instance (MonadEtherState tag s m) => MonadEtherState tag s (EtherStateT tag' s' m) where
92+ etherGet proxy = lift (etherGet proxy)
93+ etherPut proxy = lift . etherPut proxy
94+ etherState proxy = lift . etherState proxy
96+-- Instances for mtl transformers
98+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.ContT r m) where
99+ etherGet proxy = lift (etherGet proxy)
100+ etherPut proxy = lift . etherPut proxy
101+ etherState proxy = lift . etherState proxy
103+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.ExceptT e m) where
104+ etherGet proxy = lift (etherGet proxy)
105+ etherPut proxy = lift . etherPut proxy
106+ etherState proxy = lift . etherState proxy
108+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.IdentityT m) where
109+ etherGet proxy = lift (etherGet proxy)
110+ etherPut proxy = lift . etherPut proxy
111+ etherState proxy = lift . etherState proxy
113+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.ListT m) where
114+ etherGet proxy = lift (etherGet proxy)
115+ etherPut proxy = lift . etherPut proxy
116+ etherState proxy = lift . etherState proxy
118+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.MaybeT m) where
119+ etherGet proxy = lift (etherGet proxy)
120+ etherPut proxy = lift . etherPut proxy
121+ etherState proxy = lift . etherState proxy
123+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.ReaderT r m) where
124+ etherGet proxy = lift (etherGet proxy)
125+ etherPut proxy = lift . etherPut proxy
126+ etherState proxy = lift . etherState proxy
128+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.Lazy.StateT s' m) where
129+ etherGet proxy = lift (etherGet proxy)
130+ etherPut proxy = lift . etherPut proxy
131+ etherState proxy = lift . etherState proxy
133+instance MonadEtherState tag s m => MonadEtherState tag s (Trans.Strict.StateT s' m) where
134+ etherGet proxy = lift (etherGet proxy)
135+ etherPut proxy = lift . etherPut proxy
136+ etherState proxy = lift . etherState proxy
138+instance (Monoid w, MonadEtherState tag s m) => MonadEtherState tag s (Trans.Lazy.WriterT w m) where
139+ etherGet proxy = lift (etherGet proxy)
140+ etherPut proxy = lift . etherPut proxy
141+ etherState proxy = lift . etherState proxy
143+instance (Monoid w, MonadEtherState tag s m) => MonadEtherState tag s (Trans.Strict.WriterT w m) where
144+ etherGet proxy = lift (etherGet proxy)
145+ etherPut proxy = lift . etherPut proxy
146+ etherState proxy = lift . etherState proxy