on master help sign in
Strict state transformer
commitb8547a896d3dce07347f31bcb91815c6e5ca988b authorIndex Int <vlad.z.4096@gmail.com> dateSat 13 Jun 2015, 13:17 (11 years ago) parent1a825a2
21 files changed+626−281
ether.cabal+8−2 src/Control/Ether/Tags.hs → src/Control/Ether/Tagged.hs+1−1 src/Control/Monad/Ether/Except/Class.hs+8−3 src/Control/Monad/Ether/Implicit/Except.hs+4 src/Control/Monad/Ether/Implicit/Reader.hs+17−5 src/Control/Monad/Ether/Implicit/State.hs+2−57 src/Control/Monad/Ether/Implicit/State/Lazy.hs+71 src/Control/Monad/Ether/Implicit/State/Strict.hs+71 src/Control/Monad/Ether/Reader/Class.hs+8−3 src/Control/Monad/Ether/State.hs+2−19 src/Control/Monad/Ether/State/Class.hs+17−7 src/Control/Monad/Ether/State/Lazy.hs+22 src/Control/Monad/Ether/State/Strict.hs+22 src/Control/Monad/Ether/Writer/Class.hs+11−4 src/Control/Monad/Trans/Ether/Except.hs+1−1 src/Control/Monad/Trans/Ether/Reader.hs+1−1 src/Control/Monad/Trans/Ether/State.hs+2−174 src/Control/Monad/Trans/Ether/State/Lazy.hs+177 src/Control/Monad/Trans/Ether/State/Strict.hs+177 src/Control/Monad/Trans/Ether/Writer.hs+3−3 test/Regression.hs+1−1
ether.cabal+8−2
@@ -23,12 +23,14 @@ source-repository head
2323
2424library
2525
26− exposed-modules: Control.Ether.Tags
27− Control.Ether.TH
26+ exposed-modules: Control.Ether.Tagged
2827 Control.Ether.Wrapped
28+ Control.Ether.TH
2929 Control.Monad.Trans.Ether.Reader
3030 Control.Monad.Trans.Ether.Writer
3131 Control.Monad.Trans.Ether.State
32+ Control.Monad.Trans.Ether.State.Lazy
33+ Control.Monad.Trans.Ether.State.Strict
3234 Control.Monad.Trans.Ether.Except
3335 Control.Monad.Ether.Reader
3436 Control.Monad.Ether.Reader.Class
@@ -36,11 +38,15 @@ library
3638 Control.Monad.Ether.Writer.Class
3739 Control.Monad.Ether.State
3840 Control.Monad.Ether.State.Class
41+ Control.Monad.Ether.State.Lazy
42+ Control.Monad.Ether.State.Strict
3943 Control.Monad.Ether.Except
4044 Control.Monad.Ether.Except.Class
4145 Control.Monad.Ether.Implicit.Reader
4246 Control.Monad.Ether.Implicit.Writer
4347 Control.Monad.Ether.Implicit.State
48+ Control.Monad.Ether.Implicit.State.Lazy
49+ Control.Monad.Ether.Implicit.State.Strict
4450 Control.Monad.Ether.Implicit.Except
4551 Control.Monad.Ether.Implicit.Except.TH
4652
src/Control/Ether/Tags.hs → src/Control/Ether/Tagged.hsrenamed+1−1
@@ -9,7 +9,7 @@
99{-# LANGUAGE MultiParamTypeClasses #-}
1010{-# LANGUAGE FunctionalDependencies #-}
1111{-# LANGUAGE DefaultSignatures #-}
12−module Control.Ether.Tags
12+module Control.Ether.Tagged
1313 ( Taggable(..)
1414 , Tagged(..)
1515 , Tags
src/Control/Monad/Ether/Except/Class.hs+8−3
@@ -21,7 +21,8 @@ import Control.Monad.Trans.Ether.Except hiding (throw, catch)
2121import qualified Control.Monad.Trans.Ether.Except as E
2222import qualified Control.Monad.Trans.Ether.Reader as R
2323import qualified Control.Monad.Trans.Ether.Writer as W
24−import qualified Control.Monad.Trans.Ether.State as S
24+import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
25+import qualified Control.Monad.Trans.Ether.State.Strict as S.S
2526import qualified Control.Ether.Util as Util
2627
2728-- for mtl instances
@@ -62,9 +63,13 @@ instance (Monoid w, MonadExcept tag e m) => MonadExcept tag e (W.WriterT tag' w
6263 throw t = lift . throw t
6364 catch t = W.liftCatch Proxy (catch t)
6465
65−instance MonadExcept tag e m => MonadExcept tag e (S.StateT tag' s m) where
66+instance MonadExcept tag e m => MonadExcept tag e (S.L.StateT tag' s m) where
6667 throw t = lift . throw t
67− catch t = S.liftCatch Proxy (catch t)
68+ catch t = S.L.liftCatch Proxy (catch t)
69+
70+instance MonadExcept tag e m => MonadExcept tag e (S.S.StateT tag' s m) where
71+ throw t = lift . throw t
72+ catch t = S.S.liftCatch Proxy (catch t)
6873
6974
7075-- Instances for mtl transformers
src/Control/Monad/Ether/Implicit/Except.hs+4
@@ -13,6 +13,7 @@ module Control.Monad.Ether.Implicit.Except
1313 , ExceptT
1414 , exceptT
1515 , runExceptT
16+ , mapExceptT
1617 ) where
1718
1819import Data.Proxy
@@ -38,3 +39,6 @@ exceptT = Explicit.exceptT Proxy
3839
3940runExceptT :: ExceptT e m a -> m (Either e a)
4041runExceptT = Explicit.runExceptT Proxy
42+
43+mapExceptT :: (m (Either e a) -> n (Either e b)) -> ExceptT e m a -> ExceptT e n b
44+mapExceptT = Explicit.mapExceptT Proxy
src/Control/Monad/Ether/Implicit/Reader.hs+17−5
@@ -1,15 +1,21 @@
11{-# LANGUAGE ConstraintKinds #-}
22{-# LANGUAGE ScopedTypeVariables #-}
33module Control.Monad.Ether.Implicit.Reader
4− ( ReaderT
5− , Reader
6− , MonadReader
7− , runReaderT
8− , runReader
4+ (
5+ -- * MonadReader class
6+ MonadReader
97 , local
108 , ask
119 , reader
1210 , asks
11+ -- * The Reader monad
12+ , Reader
13+ , runReader
14+ -- * The ReaderT monad transformer
15+ , ReaderT
16+ , readerT
17+ , runReaderT
18+ , mapReaderT
1319 ) where
1420
1521import Data.Proxy
@@ -18,12 +24,18 @@ import qualified Control.Monad.Ether.Reader as Explicit
1824type ReaderT r = Explicit.ReaderT r r
1925type Reader r = Explicit.Reader r r
2026
27+readerT :: (r -> m a) -> ReaderT r m a
28+readerT = Explicit.readerT Proxy
29+
2130runReaderT :: ReaderT r m a -> r -> m a
2231runReaderT = Explicit.runReaderT Proxy
2332
2433runReader :: Reader r a -> r -> a
2534runReader = Explicit.runReader Proxy
2635
36+mapReaderT :: (m a -> n b) -> ReaderT r m a -> ReaderT r n b
37+mapReaderT = Explicit.mapReaderT Proxy
38+
2739type MonadReader r = Explicit.MonadReader r r
2840
2941local :: forall m r a . MonadReader r m => (r -> r) -> m a -> m a
src/Control/Monad/Ether/Implicit/State.hs+2−57
@@ -1,60 +1,5 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
31module Control.Monad.Ether.Implicit.State
4− ( StateT
5− , State
6− , runStateT
7− , runState
8− , evalStateT
9− , evalState
10− , execStateT
11− , execState
12− --
13− , MonadState
14− , get
15− , gets
16− , put
17− , state
18− , modify
2+ ( module Control.Monad.Ether.Implicit.State.Lazy
193 ) where
204
21−import Data.Proxy
22−import qualified Control.Monad.Ether.State as Explicit
23−
24−type StateT s = Explicit.StateT s s
25−type State s = Explicit.State s s
26−
27−runStateT :: StateT s m a -> s -> m (a, s)
28−runStateT = Explicit.runStateT Proxy
29−
30−runState :: State s a -> s -> (a, s)
31−runState = Explicit.runState Proxy
32−
33−evalStateT :: Monad m => StateT s m a -> s -> m a
34−evalStateT = Explicit.evalStateT Proxy
35−
36−evalState :: State s a -> s -> a
37−evalState = Explicit.evalState Proxy
38−
39−execStateT :: Monad m => StateT s m a -> s -> m s
40−execStateT = Explicit.execStateT Proxy
41−
42−execState :: State s a -> s -> s
43−execState = Explicit.execState Proxy
44−
45−type MonadState s = Explicit.MonadState s s
46−
47−get :: forall m s . MonadState s m => m s
48−get = Explicit.get (Proxy :: Proxy s)
49−
50−gets :: forall m s a . MonadState s m => (s -> a) -> m a
51−gets = Explicit.gets (Proxy :: Proxy s)
52−
53−put :: forall m s . MonadState s m => s -> m ()
54−put = Explicit.put (Proxy :: Proxy s)
55−
56−state :: forall m s a . MonadState s m => (s -> (a, s)) -> m a
57−state = Explicit.state (Proxy :: Proxy s)
58−
59−modify :: forall m s . MonadState s m => (s -> s) -> m ()
60−modify = Explicit.modify (Proxy :: Proxy s)
5+import Control.Monad.Ether.Implicit.State.Lazy
src/Control/Monad/Ether/Implicit/State/Lazy.hsnew file+71
@@ -0,0 +1,71 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+{-# LANGUAGE ScopedTypeVariables #-}
3+module Control.Monad.Ether.Implicit.State.Lazy
4+ (
5+ -- * MonadState class
6+ MonadState
7+ , get
8+ , put
9+ , state
10+ , modify
11+ , gets
12+ -- * The State monad
13+ , State
14+ , runState
15+ , evalState
16+ , execState
17+ -- * The StateT monad transformer
18+ , StateT
19+ , stateT
20+ , runStateT
21+ , evalStateT
22+ , execStateT
23+ , mapStateT
24+ ) where
25+
26+import Data.Proxy
27+import qualified Control.Monad.Ether.State.Lazy as Explicit
28+
29+type StateT s = Explicit.StateT s s
30+type State s = Explicit.State s s
31+
32+stateT :: (s -> m (a, s)) -> StateT s m a
33+stateT = Explicit.stateT Proxy
34+
35+runStateT :: StateT s m a -> s -> m (a, s)
36+runStateT = Explicit.runStateT Proxy
37+
38+runState :: State s a -> s -> (a, s)
39+runState = Explicit.runState Proxy
40+
41+evalStateT :: Monad m => StateT s m a -> s -> m a
42+evalStateT = Explicit.evalStateT Proxy
43+
44+evalState :: State s a -> s -> a
45+evalState = Explicit.evalState Proxy
46+
47+execStateT :: Monad m => StateT s m a -> s -> m s
48+execStateT = Explicit.execStateT Proxy
49+
50+execState :: State s a -> s -> s
51+execState = Explicit.execState Proxy
52+
53+mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
54+mapStateT = Explicit.mapStateT Proxy
55+
56+type MonadState s = Explicit.MonadState s s
57+
58+get :: forall m s . MonadState s m => m s
59+get = Explicit.get (Proxy :: Proxy s)
60+
61+gets :: forall m s a . MonadState s m => (s -> a) -> m a
62+gets = Explicit.gets (Proxy :: Proxy s)
63+
64+put :: forall m s . MonadState s m => s -> m ()
65+put = Explicit.put (Proxy :: Proxy s)
66+
67+state :: forall m s a . MonadState s m => (s -> (a, s)) -> m a
68+state = Explicit.state (Proxy :: Proxy s)
69+
70+modify :: forall m s . MonadState s m => (s -> s) -> m ()
71+modify = Explicit.modify (Proxy :: Proxy s)
src/Control/Monad/Ether/Implicit/State/Strict.hsnew file+71
@@ -0,0 +1,71 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+{-# LANGUAGE ScopedTypeVariables #-}
3+module Control.Monad.Ether.Implicit.State.Strict
4+ (
5+ -- * MonadState class
6+ MonadState
7+ , get
8+ , put
9+ , state
10+ , modify
11+ , gets
12+ -- * The State monad
13+ , State
14+ , runState
15+ , evalState
16+ , execState
17+ -- * The StateT monad transformer
18+ , StateT
19+ , stateT
20+ , runStateT
21+ , evalStateT
22+ , execStateT
23+ , mapStateT
24+ ) where
25+
26+import Data.Proxy
27+import qualified Control.Monad.Ether.State.Strict as Explicit
28+
29+type StateT s = Explicit.StateT s s
30+type State s = Explicit.State s s
31+
32+stateT :: (s -> m (a, s)) -> StateT s m a
33+stateT = Explicit.stateT Proxy
34+
35+runStateT :: StateT s m a -> s -> m (a, s)
36+runStateT = Explicit.runStateT Proxy
37+
38+runState :: State s a -> s -> (a, s)
39+runState = Explicit.runState Proxy
40+
41+evalStateT :: Monad m => StateT s m a -> s -> m a
42+evalStateT = Explicit.evalStateT Proxy
43+
44+evalState :: State s a -> s -> a
45+evalState = Explicit.evalState Proxy
46+
47+execStateT :: Monad m => StateT s m a -> s -> m s
48+execStateT = Explicit.execStateT Proxy
49+
50+execState :: State s a -> s -> s
51+execState = Explicit.execState Proxy
52+
53+mapStateT :: (m (a, s) -> n (b, s)) -> StateT s m a -> StateT s n b
54+mapStateT = Explicit.mapStateT Proxy
55+
56+type MonadState s = Explicit.MonadState s s
57+
58+get :: forall m s . MonadState s m => m s
59+get = Explicit.get (Proxy :: Proxy s)
60+
61+gets :: forall m s a . MonadState s m => (s -> a) -> m a
62+gets = Explicit.gets (Proxy :: Proxy s)
63+
64+put :: forall m s . MonadState s m => s -> m ()
65+put = Explicit.put (Proxy :: Proxy s)
66+
67+state :: forall m s a . MonadState s m => (s -> (a, s)) -> m a
68+state = Explicit.state (Proxy :: Proxy s)
69+
70+modify :: forall m s . MonadState s m => (s -> s) -> m ()
71+modify = Explicit.modify (Proxy :: Proxy s)
src/Control/Monad/Ether/Reader/Class.hs+8−3
@@ -19,10 +19,11 @@ import Data.Proxy (Proxy(Proxy))
1919import Control.Monad.Trans (lift)
2020
2121import Control.Monad.Trans.Ether.Writer (WriterT, mapWriterT)
22−import Control.Monad.Trans.Ether.State (StateT , mapStateT)
2322import Control.Monad.Trans.Ether.Except (ExceptT, mapExceptT)
2423import Control.Monad.Trans.Ether.Reader hiding (reader, ask, local)
2524import qualified Control.Monad.Trans.Ether.Reader as R
25+import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
26+import qualified Control.Monad.Trans.Ether.State.Strict as S.S
2627
2728-- for mtl instances
2829import qualified Control.Monad.Trans.Cont as Trans (ContT , liftLocal)
@@ -85,9 +86,13 @@ instance (Monoid w, MonadReader tag r m) => MonadReader tag r (WriterT tag' w m)
8586 ask t = lift (ask t)
8687 local t = mapWriterT Proxy . local t
8788
88−instance (MonadReader tag r m) => MonadReader tag r (StateT tag' s m) where
89+instance (MonadReader tag r m) => MonadReader tag r (S.L.StateT tag' s m) where
8990 ask t = lift (ask t)
90− local t = mapStateT Proxy . local t
91+ local t = S.L.mapStateT Proxy . local t
92+
93+instance (MonadReader tag r m) => MonadReader tag r (S.S.StateT tag' s m) where
94+ ask t = lift (ask t)
95+ local t = S.S.mapStateT Proxy . local t
9196
9297instance (MonadReader tag r m) => MonadReader tag r (ExceptT tag' e m) where
9398 ask t = lift (ask t)
src/Control/Monad/Ether/State.hs+2−19
@@ -1,22 +1,5 @@
11module Control.Monad.Ether.State
2− (
3− -- * MonadState class
4− MonadState(..)
5− , modify
6− , gets
7− -- * The State monad
8− , State
9− , runState
10− , evalState
11− , execState
12− -- * The StateT monad transformer
13− , StateT
14− , stateT
15− , runStateT
16− , evalStateT
17− , execStateT
18− , mapStateT
2+ ( module Control.Monad.Ether.State.Lazy
193 ) where
204
21−import Control.Monad.Ether.State.Class
22−import Control.Monad.Trans.Ether.State hiding (state, get, put)
5+import Control.Monad.Ether.State.Lazy
src/Control/Monad/Ether/State/Class.hs+17−7
@@ -21,8 +21,8 @@ import Control.Monad.Trans (lift)
2121import Control.Monad.Trans.Ether.Reader (ReaderT)
2222import Control.Monad.Trans.Ether.Writer (WriterT)
2323import Control.Monad.Trans.Ether.Except (ExceptT)
24−import Control.Monad.Trans.Ether.State hiding (state, get, put)
25−import qualified Control.Monad.Trans.Ether.State as S
24+import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
25+import qualified Control.Monad.Trans.Ether.State.Strict as S.S
2626
2727-- for mtl instances
2828import qualified Control.Monad.Trans.Cont as Trans (ContT)
@@ -64,12 +64,22 @@ modify t f = state t (\s -> ((), f s))
6464gets :: MonadState tag s m => proxy tag -> (s -> a) -> m a
6565gets t f = fmap f (get t)
6666
67−instance {-# OVERLAPPING #-} Monad m => MonadState tag s (StateT tag s m) where
68− get = S.get
69− put = S.put
70− state = S.state
67+instance {-# OVERLAPPING #-} Monad m => MonadState tag s (S.L.StateT tag s m) where
68+ get = S.L.get
69+ put = S.L.put
70+ state = S.L.state
7171
72−instance MonadState tag s m => MonadState tag s (StateT tag' s' m) where
72+instance MonadState tag s m => MonadState tag s (S.L.StateT tag' s' m) where
73+ get t = lift (get t)
74+ put t = lift . put t
75+ state t = lift . state t
76+
77+instance {-# OVERLAPPING #-} Monad m => MonadState tag s (S.S.StateT tag s m) where
78+ get = S.S.get
79+ put = S.S.put
80+ state = S.S.state
81+
82+instance MonadState tag s m => MonadState tag s (S.S.StateT tag' s' m) where
7383 get t = lift (get t)
7484 put t = lift . put t
7585 state t = lift . state t
src/Control/Monad/Ether/State/Lazy.hsnew file+22
@@ -0,0 +1,22 @@
1+module Control.Monad.Ether.State.Lazy
2+ (
3+ -- * MonadState class
4+ MonadState(..)
5+ , modify
6+ , gets
7+ -- * The State monad
8+ , State
9+ , runState
10+ , evalState
11+ , execState
12+ -- * The StateT monad transformer
13+ , StateT
14+ , stateT
15+ , runStateT
16+ , evalStateT
17+ , execStateT
18+ , mapStateT
19+ ) where
20+
21+import Control.Monad.Ether.State.Class
22+import Control.Monad.Trans.Ether.State.Lazy hiding (state, get, put)
src/Control/Monad/Ether/State/Strict.hsnew file+22
@@ -0,0 +1,22 @@
1+module Control.Monad.Ether.State.Strict
2+ (
3+ -- * MonadState class
4+ MonadState(..)
5+ , modify
6+ , gets
7+ -- * The State monad
8+ , State
9+ , runState
10+ , evalState
11+ , execState
12+ -- * The StateT monad transformer
13+ , StateT
14+ , stateT
15+ , runStateT
16+ , evalStateT
17+ , execStateT
18+ , mapStateT
19+ ) where
20+
21+import Control.Monad.Ether.State.Class
22+import Control.Monad.Trans.Ether.State.Strict hiding (state, get, put)
src/Control/Monad/Ether/Writer/Class.hs+11−4
@@ -21,7 +21,8 @@ import Control.Monad.Trans (lift)
2121
2222import Control.Monad.Trans.Ether.Writer hiding (writer, tell, listen, pass)
2323import qualified Control.Monad.Trans.Ether.Reader as R
24−import qualified Control.Monad.Trans.Ether.State as S
24+import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
25+import qualified Control.Monad.Trans.Ether.State.Strict as S.S
2526import qualified Control.Monad.Trans.Ether.Except as E
2627import qualified Control.Monad.Trans.Ether.Writer as W
2728import qualified Control.Ether.Util as Util
@@ -93,11 +94,17 @@ instance (MonadWriter tag w m) => MonadWriter tag w (E.ExceptT tag' e m) where
9394 listen t = E.liftListen Proxy (listen t)
9495 pass t = E.liftPass Proxy (pass t)
9596
96−instance (MonadWriter tag w m) => MonadWriter tag w (S.StateT tag' e m) where
97+instance (MonadWriter tag w m) => MonadWriter tag w (S.L.StateT tag' e m) where
9798 writer t = lift . writer t
9899 tell t = lift . tell t
99− listen t = S.liftListen Proxy (listen t)
100− pass t = S.liftPass Proxy (pass t)
100+ listen t = S.L.liftListen Proxy (listen t)
101+ pass t = S.L.liftPass Proxy (pass t)
102+
103+instance (MonadWriter tag w m) => MonadWriter tag w (S.S.StateT tag' e m) where
104+ writer t = lift . writer t
105+ tell t = lift . tell t
106+ listen t = S.S.liftListen Proxy (listen t)
107+ pass t = S.S.liftPass Proxy (pass t)
101108
102109-- Instances for mtl transformers
103110
src/Control/Monad/Trans/Ether/Except.hs+1−1
@@ -36,7 +36,7 @@ import Control.Monad (MonadPlus)
3636import Control.Monad.Fix (MonadFix)
3737import Control.Monad.Trans.Class (MonadTrans, lift)
3838import Control.Monad.IO.Class (MonadIO)
39−import Control.Ether.Tags (Taggable(..), Tagged(..))
39+import Control.Ether.Tagged (Taggable(..), Tagged(..))
4040import qualified Control.Ether.Util as Util
4141import GHC.Generics (Generic)
4242import qualified Control.Newtype as NT
src/Control/Monad/Trans/Ether/Reader.hs+1−1
@@ -35,7 +35,7 @@ import Control.Monad (MonadPlus)
3535import Control.Monad.Fix (MonadFix)
3636import Control.Monad.Trans.Class (MonadTrans, lift)
3737import Control.Monad.IO.Class (MonadIO)
38−import Control.Ether.Tags (Taggable(..), Tagged(..))
38+import Control.Ether.Tagged (Taggable(..), Tagged(..))
3939import GHC.Generics (Generic)
4040import qualified Control.Newtype as NT
4141
src/Control/Monad/Trans/Ether/State.hs+2−174
@@ -1,177 +1,5 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE FlexibleContexts #-}
6−{-# LANGUAGE UndecidableInstances #-}
7−{-# LANGUAGE DataKinds #-}
8−{-# LANGUAGE TypeOperators #-}
9−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
101module Control.Monad.Trans.Ether.State
11− (
12− -- * The State monad
13− State
14− , state
15− , runState
16− , evalState
17− , execState
18− -- * The StateT monad transformer
19− , StateT
20− , stateT
21− , runStateT
22− , evalStateT
23− , execStateT
24− , mapStateT
25− -- * State operations
26− , get
27− , put
28− -- * Litfing other operations
29− , liftCatch
30− , liftCallCC'
31− , liftListen
32− , liftPass
2+ ( module Control.Monad.Trans.Ether.State.Lazy
333 ) where
344
35−import Data.Proxy (Proxy(Proxy))
36−import Data.Functor.Identity (Identity(..))
37−import Data.Coerce (coerce)
38−import Control.Applicative (Alternative)
39−import Control.Monad (MonadPlus)
40−import Control.Monad.Fix (MonadFix)
41−import Control.Monad.Trans.Class (MonadTrans, lift)
42−import Control.Monad.IO.Class (MonadIO)
43−import Control.Ether.Tags (Taggable(..), Tagged(..))
44−import GHC.Generics (Generic)
45−import qualified Control.Newtype as NT
46−
47−import qualified Control.Monad.Signatures as Sig
48−import qualified Control.Monad.Trans.State.Lazy as Trans
49−
50−import qualified Control.Monad.Cont.Class as Class
51−import qualified Control.Monad.Reader.Class as Class
52−import qualified Control.Monad.State.Class as Class
53−import qualified Control.Monad.Writer.Class as Class
54−import qualified Control.Monad.Error.Class as Class
55−
56−
57−-- | The parametrizable state monad.
58−--
59−-- Computations have access to a mutable state.
60−--
61−-- The 'return' function leaves the state unchanged, while '>>=' uses
62−-- the final state of the first computation as the initial state of the second.
63−type State tag r = StateT tag r Identity
64−
65−-- | The state monad transformer.
66−--
67−-- The 'return' function leaves the state unchanged, while '>>=' uses
68−-- the final state of the first computation as the initial state of the second.
69−newtype StateT tag s m a = StateT (Trans.StateT s m a)
70− deriving ( Generic
71− , Functor, Applicative, Alternative, Monad, MonadPlus
72− , MonadFix, MonadTrans, MonadIO )
73−
74−instance NT.Newtype (StateT tag s m a)
75−
76−instance Taggable (StateT tag s m) where
77− type Tag (StateT tag s m) = 'Just tag
78− type Inner (StateT tag s m) = 'Just m
79−
80−instance Tagged (StateT tag s m) tag where
81− type Untagged (StateT tag s m) = Trans.StateT s m
82−
83−-- | Constructor for computations in the state monad transformer.
84−stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
85−stateT t = tagged t . Trans.StateT
86−
87−-- | Constructor for computations in the state monad
88−-- (the inverse of 'runState').
89−state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
90−state t = tagged t . Trans.state
91−
92−-- | Runs a 'StateT' with the given initial state
93−-- and returns both the final value and the final state.
94−runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
95−runStateT t = Trans.runStateT . untagged t
96−
97−-- | Runs a 'StateT' with the given initial state
98−-- and returns the final value, discarding the final state.
99−evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
100−evalStateT t = Trans.evalStateT . untagged t
101−
102−-- | Runs a 'StateT' with the given initial state
103−-- and returns the final state, discarding the final value.
104−execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
105−execStateT t = Trans.execStateT . untagged t
106−
107−-- | Runs a 'State' with the given initial state
108−-- and returns both the final value and the final state.
109−runState :: proxy tag -> State tag s a -> s -> (a, s)
110−runState t = Trans.runState . untagged t
111−
112−-- | Runs a 'State' with the given initial state
113−-- and returns the final value, discarding the final state.
114−evalState :: proxy tag -> State tag s a -> s -> a
115−evalState t = Trans.evalState . untagged t
116−
117−-- | Runs a 'State' with the given initial state
118−-- and returns the final state, discarding the final value.
119−execState :: proxy tag -> State tag s a -> s -> s
120−execState t = Trans.execState . untagged t
121−
122−-- | Transform the computation inside a 'StateT'.
123−--
124−-- * @'runStateT' tag ('mapStateT' tag f m) = f . 'runStateT' tag m@
125−mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
126−mapStateT t f m = tagged t $ Trans.mapStateT f (coerce m)
127−
128−-- | Fetch the current value of the state within the monad.
129−get :: Monad m => proxy tag -> StateT tag s m s
130−get t = tagged t Trans.get
131−
132−-- | Set the value of the state within the monad.
133−put :: Monad m => proxy tag -> s -> StateT tag s m ()
134−put t = tagged t . Trans.put
135−
136−-- | Lift a @catchE@ operation to the new monad.
137−liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
138−liftCatch t f m h = tagged t $ Trans.liftCatch f (coerce m) (coerce h)
139−
140−-- | Lift a @listen@ operation to the new monad.
141−liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
142−liftListen t listen m = tagged t $ Trans.liftListen listen (coerce m)
143−
144−-- | In-situ lifting of a @callCC@ operation to the new monad.
145−-- This version uses the current state on entering the continuation.
146−-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
147−liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
148−liftCallCC' t callCC f = tagged t $ Trans.liftCallCC' callCC (coerce f)
149−
150−-- | Lift a @pass@ operation to the new monad.
151−liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
152−liftPass t pass m = tagged t $ Trans.liftPass pass (coerce m)
153−
154−-- Instances for mtl classes
155−
156−instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
157− callCC = liftCallCC' Proxy Class.callCC
158−
159−instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
160− ask = lift Class.ask
161− local = mapStateT Proxy . Class.local
162− reader = lift . Class.reader
163−
164−instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
165− get = lift Class.get
166− put = lift . Class.put
167− state = lift . Class.state
168−
169−instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
170− writer = lift . Class.writer
171− tell = lift . Class.tell
172− listen = liftListen Proxy Class.listen
173− pass = liftPass Proxy Class.pass
174−
175−instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
176− throwError = lift . Class.throwError
177− catchError = liftCatch Proxy Class.catchError
5+import Control.Monad.Trans.Ether.State.Lazy
src/Control/Monad/Trans/Ether/State/Lazy.hsnew file+177
@@ -0,0 +1,177 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE MultiParamTypeClasses #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FlexibleContexts #-}
6+{-# LANGUAGE UndecidableInstances #-}
7+{-# LANGUAGE DataKinds #-}
8+{-# LANGUAGE TypeOperators #-}
9+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10+module Control.Monad.Trans.Ether.State.Lazy
11+ (
12+ -- * The State monad
13+ State
14+ , state
15+ , runState
16+ , evalState
17+ , execState
18+ -- * The StateT monad transformer
19+ , StateT
20+ , stateT
21+ , runStateT
22+ , evalStateT
23+ , execStateT
24+ , mapStateT
25+ -- * State operations
26+ , get
27+ , put
28+ -- * Litfing other operations
29+ , liftCatch
30+ , liftCallCC'
31+ , liftListen
32+ , liftPass
33+ ) where
34+
35+import Data.Proxy (Proxy(Proxy))
36+import Data.Functor.Identity (Identity(..))
37+import Data.Coerce (coerce)
38+import Control.Applicative (Alternative)
39+import Control.Monad (MonadPlus)
40+import Control.Monad.Fix (MonadFix)
41+import Control.Monad.Trans.Class (MonadTrans, lift)
42+import Control.Monad.IO.Class (MonadIO)
43+import Control.Ether.Tagged (Taggable(..), Tagged(..))
44+import GHC.Generics (Generic)
45+import qualified Control.Newtype as NT
46+
47+import qualified Control.Monad.Signatures as Sig
48+import qualified Control.Monad.Trans.State.Lazy as Trans
49+
50+import qualified Control.Monad.Cont.Class as Class
51+import qualified Control.Monad.Reader.Class as Class
52+import qualified Control.Monad.State.Class as Class
53+import qualified Control.Monad.Writer.Class as Class
54+import qualified Control.Monad.Error.Class as Class
55+
56+
57+-- | The parametrizable state monad.
58+--
59+-- Computations have access to a mutable state.
60+--
61+-- The 'return' function leaves the state unchanged, while '>>=' uses
62+-- the final state of the first computation as the initial state of the second.
63+type State tag r = StateT tag r Identity
64+
65+-- | The state monad transformer.
66+--
67+-- The 'return' function leaves the state unchanged, while '>>=' uses
68+-- the final state of the first computation as the initial state of the second.
69+newtype StateT tag s m a = StateT (Trans.StateT s m a)
70+ deriving ( Generic
71+ , Functor, Applicative, Alternative, Monad, MonadPlus
72+ , MonadFix, MonadTrans, MonadIO )
73+
74+instance NT.Newtype (StateT tag s m a)
75+
76+instance Taggable (StateT tag s m) where
77+ type Tag (StateT tag s m) = 'Just tag
78+ type Inner (StateT tag s m) = 'Just m
79+
80+instance Tagged (StateT tag s m) tag where
81+ type Untagged (StateT tag s m) = Trans.StateT s m
82+
83+-- | Constructor for computations in the state monad transformer.
84+stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
85+stateT t = tagged t . Trans.StateT
86+
87+-- | Constructor for computations in the state monad
88+-- (the inverse of 'runState').
89+state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
90+state t = tagged t . Trans.state
91+
92+-- | Runs a 'StateT' with the given initial state
93+-- and returns both the final value and the final state.
94+runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
95+runStateT t = Trans.runStateT . untagged t
96+
97+-- | Runs a 'StateT' with the given initial state
98+-- and returns the final value, discarding the final state.
99+evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
100+evalStateT t = Trans.evalStateT . untagged t
101+
102+-- | Runs a 'StateT' with the given initial state
103+-- and returns the final state, discarding the final value.
104+execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
105+execStateT t = Trans.execStateT . untagged t
106+
107+-- | Runs a 'State' with the given initial state
108+-- and returns both the final value and the final state.
109+runState :: proxy tag -> State tag s a -> s -> (a, s)
110+runState t = Trans.runState . untagged t
111+
112+-- | Runs a 'State' with the given initial state
113+-- and returns the final value, discarding the final state.
114+evalState :: proxy tag -> State tag s a -> s -> a
115+evalState t = Trans.evalState . untagged t
116+
117+-- | Runs a 'State' with the given initial state
118+-- and returns the final state, discarding the final value.
119+execState :: proxy tag -> State tag s a -> s -> s
120+execState t = Trans.execState . untagged t
121+
122+-- | Transform the computation inside a 'StateT'.
123+--
124+-- * @'runStateT' tag ('mapStateT' tag f m) = f . 'runStateT' tag m@
125+mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
126+mapStateT t f m = tagged t $ Trans.mapStateT f (coerce m)
127+
128+-- | Fetch the current value of the state within the monad.
129+get :: Monad m => proxy tag -> StateT tag s m s
130+get t = tagged t Trans.get
131+
132+-- | Set the value of the state within the monad.
133+put :: Monad m => proxy tag -> s -> StateT tag s m ()
134+put t = tagged t . Trans.put
135+
136+-- | Lift a @catchE@ operation to the new monad.
137+liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
138+liftCatch t f m h = tagged t $ Trans.liftCatch f (coerce m) (coerce h)
139+
140+-- | Lift a @listen@ operation to the new monad.
141+liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
142+liftListen t listen m = tagged t $ Trans.liftListen listen (coerce m)
143+
144+-- | In-situ lifting of a @callCC@ operation to the new monad.
145+-- This version uses the current state on entering the continuation.
146+-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
147+liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
148+liftCallCC' t callCC f = tagged t $ Trans.liftCallCC' callCC (coerce f)
149+
150+-- | Lift a @pass@ operation to the new monad.
151+liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
152+liftPass t pass m = tagged t $ Trans.liftPass pass (coerce m)
153+
154+-- Instances for mtl classes
155+
156+instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
157+ callCC = liftCallCC' Proxy Class.callCC
158+
159+instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
160+ ask = lift Class.ask
161+ local = mapStateT Proxy . Class.local
162+ reader = lift . Class.reader
163+
164+instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
165+ get = lift Class.get
166+ put = lift . Class.put
167+ state = lift . Class.state
168+
169+instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
170+ writer = lift . Class.writer
171+ tell = lift . Class.tell
172+ listen = liftListen Proxy Class.listen
173+ pass = liftPass Proxy Class.pass
174+
175+instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
176+ throwError = lift . Class.throwError
177+ catchError = liftCatch Proxy Class.catchError
src/Control/Monad/Trans/Ether/State/Strict.hsnew file+177
@@ -0,0 +1,177 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE MultiParamTypeClasses #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FlexibleContexts #-}
6+{-# LANGUAGE UndecidableInstances #-}
7+{-# LANGUAGE DataKinds #-}
8+{-# LANGUAGE TypeOperators #-}
9+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10+module Control.Monad.Trans.Ether.State.Strict
11+ (
12+ -- * The State monad
13+ State
14+ , state
15+ , runState
16+ , evalState
17+ , execState
18+ -- * The StateT monad transformer
19+ , StateT
20+ , stateT
21+ , runStateT
22+ , evalStateT
23+ , execStateT
24+ , mapStateT
25+ -- * State operations
26+ , get
27+ , put
28+ -- * Litfing other operations
29+ , liftCatch
30+ , liftCallCC'
31+ , liftListen
32+ , liftPass
33+ ) where
34+
35+import Data.Proxy (Proxy(Proxy))
36+import Data.Functor.Identity (Identity(..))
37+import Data.Coerce (coerce)
38+import Control.Applicative (Alternative)
39+import Control.Monad (MonadPlus)
40+import Control.Monad.Fix (MonadFix)
41+import Control.Monad.Trans.Class (MonadTrans, lift)
42+import Control.Monad.IO.Class (MonadIO)
43+import Control.Ether.Tagged (Taggable(..), Tagged(..))
44+import GHC.Generics (Generic)
45+import qualified Control.Newtype as NT
46+
47+import qualified Control.Monad.Signatures as Sig
48+import qualified Control.Monad.Trans.State.Strict as Trans
49+
50+import qualified Control.Monad.Cont.Class as Class
51+import qualified Control.Monad.Reader.Class as Class
52+import qualified Control.Monad.State.Class as Class
53+import qualified Control.Monad.Writer.Class as Class
54+import qualified Control.Monad.Error.Class as Class
55+
56+
57+-- | The parametrizable state monad.
58+--
59+-- Computations have access to a mutable state.
60+--
61+-- The 'return' function leaves the state unchanged, while '>>=' uses
62+-- the final state of the first computation as the initial state of the second.
63+type State tag r = StateT tag r Identity
64+
65+-- | The state monad transformer.
66+--
67+-- The 'return' function leaves the state unchanged, while '>>=' uses
68+-- the final state of the first computation as the initial state of the second.
69+newtype StateT tag s m a = StateT (Trans.StateT s m a)
70+ deriving ( Generic
71+ , Functor, Applicative, Alternative, Monad, MonadPlus
72+ , MonadFix, MonadTrans, MonadIO )
73+
74+instance NT.Newtype (StateT tag s m a)
75+
76+instance Taggable (StateT tag s m) where
77+ type Tag (StateT tag s m) = 'Just tag
78+ type Inner (StateT tag s m) = 'Just m
79+
80+instance Tagged (StateT tag s m) tag where
81+ type Untagged (StateT tag s m) = Trans.StateT s m
82+
83+-- | Constructor for computations in the state monad transformer.
84+stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
85+stateT t = tagged t . Trans.StateT
86+
87+-- | Constructor for computations in the state monad
88+-- (the inverse of 'runState').
89+state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
90+state t = tagged t . Trans.state
91+
92+-- | Runs a 'StateT' with the given initial state
93+-- and returns both the final value and the final state.
94+runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
95+runStateT t = Trans.runStateT . untagged t
96+
97+-- | Runs a 'StateT' with the given initial state
98+-- and returns the final value, discarding the final state.
99+evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
100+evalStateT t = Trans.evalStateT . untagged t
101+
102+-- | Runs a 'StateT' with the given initial state
103+-- and returns the final state, discarding the final value.
104+execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
105+execStateT t = Trans.execStateT . untagged t
106+
107+-- | Runs a 'State' with the given initial state
108+-- and returns both the final value and the final state.
109+runState :: proxy tag -> State tag s a -> s -> (a, s)
110+runState t = Trans.runState . untagged t
111+
112+-- | Runs a 'State' with the given initial state
113+-- and returns the final value, discarding the final state.
114+evalState :: proxy tag -> State tag s a -> s -> a
115+evalState t = Trans.evalState . untagged t
116+
117+-- | Runs a 'State' with the given initial state
118+-- and returns the final state, discarding the final value.
119+execState :: proxy tag -> State tag s a -> s -> s
120+execState t = Trans.execState . untagged t
121+
122+-- | Transform the computation inside a 'StateT'.
123+--
124+-- * @'runStateT' tag ('mapStateT' tag f m) = f . 'runStateT' tag m@
125+mapStateT :: proxy tag -> (m (a, s) -> n (b, s)) -> StateT tag s m a -> StateT tag s n b
126+mapStateT t f m = tagged t $ Trans.mapStateT f (coerce m)
127+
128+-- | Fetch the current value of the state within the monad.
129+get :: Monad m => proxy tag -> StateT tag s m s
130+get t = tagged t Trans.get
131+
132+-- | Set the value of the state within the monad.
133+put :: Monad m => proxy tag -> s -> StateT tag s m ()
134+put t = tagged t . Trans.put
135+
136+-- | Lift a @catchE@ operation to the new monad.
137+liftCatch :: proxy tag -> Sig.Catch e m (a, s) -> Sig.Catch e (StateT tag s m) a
138+liftCatch t f m h = tagged t $ Trans.liftCatch f (coerce m) (coerce h)
139+
140+-- | Lift a @listen@ operation to the new monad.
141+liftListen :: Monad m => proxy tag -> Sig.Listen w m (a, s) -> Sig.Listen w (StateT tag s m) a
142+liftListen t listen m = tagged t $ Trans.liftListen listen (coerce m)
143+
144+-- | In-situ lifting of a @callCC@ operation to the new monad.
145+-- This version uses the current state on entering the continuation.
146+-- It does not satisfy the uniformity property (see "Control.Monad.Signatures").
147+liftCallCC' :: proxy tag -> Sig.CallCC m (a, s) (b, s) -> Sig.CallCC (StateT tag s m) a b
148+liftCallCC' t callCC f = tagged t $ Trans.liftCallCC' callCC (coerce f)
149+
150+-- | Lift a @pass@ operation to the new monad.
151+liftPass :: Monad m => proxy tag -> Sig.Pass w m (a,s) -> Sig.Pass w (StateT tag s m) a
152+liftPass t pass m = tagged t $ Trans.liftPass pass (coerce m)
153+
154+-- Instances for mtl classes
155+
156+instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
157+ callCC = liftCallCC' Proxy Class.callCC
158+
159+instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
160+ ask = lift Class.ask
161+ local = mapStateT Proxy . Class.local
162+ reader = lift . Class.reader
163+
164+instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
165+ get = lift Class.get
166+ put = lift . Class.put
167+ state = lift . Class.state
168+
169+instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
170+ writer = lift . Class.writer
171+ tell = lift . Class.tell
172+ listen = liftListen Proxy Class.listen
173+ pass = liftPass Proxy Class.pass
174+
175+instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
176+ throwError = lift . Class.throwError
177+ catchError = liftCatch Proxy Class.catchError
src/Control/Monad/Trans/Ether/Writer.hs+3−3
@@ -39,7 +39,7 @@ import Control.Monad (MonadPlus)
3939import Control.Monad.Fix (MonadFix)
4040import Control.Monad.Trans.Class (MonadTrans, lift)
4141import Control.Monad.IO.Class (MonadIO)
42−import Control.Ether.Tags (Taggable(..), Tagged(..))
42+import Control.Ether.Tagged (Taggable(..), Tagged(..))
4343import qualified Control.Ether.Util as Util
4444import GHC.Generics (Generic)
4545import qualified Control.Newtype as NT
@@ -134,11 +134,11 @@ liftCallCC t callCC f = tagged t $ Trans.liftCallCC callCC (coerce f)
134134
135135-- | Lift a @listen@ operation to the new monad.
136136liftListen :: Monad m => proxy tag -> Sig.Listen w' m (a, w) -> Sig.Listen w' (WriterT tag w m) a
137−liftListen t listen m = tagged t $ Util.liftListen_WriterT listen (coerce m)
137+liftListen t f m = tagged t $ Util.liftListen_WriterT f (coerce m)
138138
139139-- | Lift a @pass@ operation to the new monad.
140140liftPass :: Monad m => proxy tag -> Sig.Pass w' m (a, w) -> Sig.Pass w' (WriterT tag w m) a
141−liftPass t pass m = tagged t $ Util.liftPass_WriterT pass (coerce m)
141+liftPass t f m = tagged t $ Util.liftPass_WriterT f (coerce m)
142142
143143instance (Monoid w, Class.MonadCont m) => Class.MonadCont (WriterT tag w m) where
144144 callCC = liftCallCC Proxy Class.callCC
test/Regression.hs+1−1
@@ -8,7 +8,7 @@
88module Main where
99
1010import Data.Functor.Identity
11−import Control.Ether.Tags
11+import Control.Ether.Tagged
1212import Control.Ether.TH
1313import Control.Ether.Wrapped
1414import Control.Monad.Ether.Reader