on master help sign in
Restructure all modules
commitd7afb5465ed03b61300f36449f826d8b7c5d0dc4 authorVladislav Zavialov <vlad.z.4096@gmail.com> dateThu 27 Apr 2017, 18:04 (9 years ago) parent237ec38
49 files changed+1497−1769
CHANGELOG.md+2 bench/Bench.hs+62−66 ether.cabal+8−31 src/Control/Ether/Abbr.hs−61 src/Control/Ether/Implicit/Abbr.hs−23 src/Control/Ether/Optic.hs−142 src/Control/Monad/Ether.hs−13 src/Control/Monad/Ether/Except/Class.hs−29 src/Control/Monad/Ether/Handle.hs−35 src/Control/Monad/Ether/Implicit.hs−13 src/Control/Monad/Ether/Implicit/Except.hs−58 src/Control/Monad/Ether/Implicit/Reader.hs−57 src/Control/Monad/Ether/Implicit/State.hs−7 src/Control/Monad/Ether/Implicit/State/Lazy.hs−82 src/Control/Monad/Ether/Implicit/State/Strict.hs−82 src/Control/Monad/Ether/Implicit/Writer.hs−77 src/Control/Monad/Ether/Reader.hs−128 src/Control/Monad/Ether/Reader/Class.hs−77 src/Control/Monad/Ether/Reader/Flatten.hs−29 src/Control/Monad/Ether/State.hs−7 src/Control/Monad/Ether/State/Class.hs−74 src/Control/Monad/Ether/State/Common.hs−90 src/Control/Monad/Ether/State/Flatten.hs−29 src/Control/Monad/Ether/State/Lazy.hs−87 src/Control/Monad/Ether/State/Strict.hs−87 src/Control/Monad/Ether/State/Zoom.hs−48 src/Control/Monad/Ether/TagAttach.hs−66 src/Control/Monad/Ether/TagReplace.hs−61 src/Control/Monad/Ether/Writer/Class.hs−49 src/Ether.hs+25 src/Control/Monad/Ether/Except.hs → src/Ether/Except.hs+82−30 src/Control/Monad/Trans/Ether/Handler.hs → src/Ether/Handler.hs+31−31 src/Ether/Internal.hs+173 src/Ether/Reader.hs+264 src/Ether/State.hs+475 src/Ether/TagDispatch.hs+188 src/Control/Monad/Ether/Writer.hs → src/Ether/Writer.hs+127−28 test/Regression/T1.hs+2−3 test/Regression/T10.hs+11−10 test/Regression/T11.hs+4−4 test/Regression/T12.hs+3−4 test/Regression/T2.hs+7−9 test/Regression/T3.hs+2−3 test/Regression/T4.hs+2−3 test/Regression/T5.hs+8−11 test/Regression/T6.hs+14−16 test/Regression/T7.hs+1−1 test/Regression/T8.hs+2−3 test/Regression/T9.hs+4−5
CHANGELOG.md+2
@@ -4,10 +4,12 @@
44* Support only GHC 8.0 and higher.
55* Use the `TypeApplications` extension to get rid of `Proxy`.
66* Remove `Control.Ether.TH`.
7+* Remove `Control.Ether.Abbr`.
78* Unify `Dispatch` and `TaggedTrans` as `Handler`.
89* Better `MonadBase` and `MonadBaseControl` instances.
910* Add flattening for `ReaderT` and `StateT`.
1011* Add zooming for `MonadState`.
12+* Simpler module structure.
1113
12140.4.1.0
1315-------
bench/Bench.hs+62−66
@@ -2,16 +2,12 @@
22
33module Main (main) where
44
5−import Criterion.Main
5+import Control.DeepSeq
6+import qualified Control.Lens as L
67import qualified Control.Monad.Reader as M
78import qualified Control.Monad.State as M
8−import qualified Control.Monad.Ether.Reader as E
9−import qualified Control.Monad.Ether.State as E
10−import qualified Control.Monad.Ether.Reader.Flatten as E.F
11−import qualified Control.Monad.Ether.State.Flatten as E.F
12−import qualified Control.Lens as L
13−import Control.Ether.Optic
14−import Control.DeepSeq
9+import Criterion.Main
10+import Ether
1511
1612id' :: a -> a
1713id' = id
@@ -71,80 +67,80 @@ run_stateCombinerMTL_flat_9
7167 M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
7268
7369readerCombinerEther_sep_9
74− :: ( E.MonadReader 1 Int m
75− , E.MonadReader 2 Int m
76− , E.MonadReader 3 Int m
77− , E.MonadReader 4 Int m
78− , E.MonadReader 5 Int m
79− , E.MonadReader 6 Int m
80− , E.MonadReader 7 Int m
81− , E.MonadReader 8 Int m
82− , E.MonadReader 9 Int m )
70+ :: ( MonadReader 1 Int m
71+ , MonadReader 2 Int m
72+ , MonadReader 3 Int m
73+ , MonadReader 4 Int m
74+ , MonadReader 5 Int m
75+ , MonadReader 6 Int m
76+ , MonadReader 7 Int m
77+ , MonadReader 8 Int m
78+ , MonadReader 9 Int m )
8379 => m ()
8480readerCombinerEther_sep_9 = rnf <$> sequenceA
85− [ E.ask @1
86− , E.ask @2
87− , E.ask @3
88− , E.ask @4
89− , E.ask @5
90− , E.ask @6
91− , E.ask @7
92− , E.ask @8
93− , E.ask @9 ]
81+ [ ask @1
82+ , ask @2
83+ , ask @3
84+ , ask @4
85+ , ask @5
86+ , ask @6
87+ , ask @7
88+ , ask @8
89+ , ask @9 ]
9490{-# NOINLINE readerCombinerEther_sep_9 #-}
9591
9692stateCombinerEther_sep_9
97− :: ( E.MonadState 1 Int m
98− , E.MonadState 2 Int m
99− , E.MonadState 3 Int m
100− , E.MonadState 4 Int m
101− , E.MonadState 5 Int m
102− , E.MonadState 6 Int m
103− , E.MonadState 7 Int m
104− , E.MonadState 8 Int m
105− , E.MonadState 9 Int m )
93+ :: ( MonadState 1 Int m
94+ , MonadState 2 Int m
95+ , MonadState 3 Int m
96+ , MonadState 4 Int m
97+ , MonadState 5 Int m
98+ , MonadState 6 Int m
99+ , MonadState 7 Int m
100+ , MonadState 8 Int m
101+ , MonadState 9 Int m )
106102 => m ()
107103stateCombinerEther_sep_9 = do
108− E.modify @1 id'
109− E.modify @2 id'
110− E.modify @3 id'
111− E.modify @4 id'
112− E.modify @5 id'
113− E.modify @6 id'
114− E.modify @7 id'
115− E.modify @8 id'
116− E.modify @9 id'
104+ modify @1 id'
105+ modify @2 id'
106+ modify @3 id'
107+ modify @4 id'
108+ modify @5 id'
109+ modify @6 id'
110+ modify @7 id'
111+ modify @8 id'
112+ modify @9 id'
117113 rnf <$> sequenceA
118− [ E.get @1
119− , E.get @2
120− , E.get @3
121− , E.get @4
122− , E.get @5
123− , E.get @6
124− , E.get @7
125− , E.get @8
126− , E.get @9 ]
114+ [ get @1
115+ , get @2
116+ , get @3
117+ , get @4
118+ , get @5
119+ , get @6
120+ , get @7
121+ , get @8
122+ , get @9 ]
127123{-# NOINLINE stateCombinerEther_sep_9 #-}
128124
129125run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
130126run_readerCombinerEther_nested_9
131127 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
132− = flip (E.runReader @9) a1
133− . flip (E.runReaderT @8) a2
134− . flip (E.runReaderT @7) a3
135− . flip (E.runReaderT @6) a4
136− . flip (E.runReaderT @5) a5
137− . flip (E.runReaderT @4) a6
138− . flip (E.runReaderT @3) a7
139− . flip (E.runReaderT @2) a8
140− . flip (E.runReaderT @1) a9
128+ = flip (runReader @9) a1
129+ . flip (runReaderT @8) a2
130+ . flip (runReaderT @7) a3
131+ . flip (runReaderT @6) a4
132+ . flip (runReaderT @5) a5
133+ . flip (runReaderT @4) a6
134+ . flip (runReaderT @3) a7
135+ . flip (runReaderT @2) a8
136+ . flip (runReaderT @1) a9
141137 $ readerCombinerEther_sep_9
142138
143139run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
144140run_readerCombinerEther_flatten_9
145141 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
146142 =
147− E.F.runReader
143+ runReaders
148144 readerCombinerEther_sep_9
149145 ( Tagged @1 a9,
150146 Tagged @2 a8,
@@ -159,12 +155,12 @@ run_readerCombinerEther_flatten_9
159155run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
160156run_readerCombinerEther_flattenhalf_9
161157 (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
162− flip E.F.runReader
158+ flip runReaders
163159 ( Tagged @1 a9,
164160 Tagged @2 a8,
165161 Tagged @3 a7,
166162 Tagged @4 a6 ) .
167− flip E.F.runReaderT
163+ flip runReadersT
168164 ( Tagged @5 a5,
169165 Tagged @6 a4,
170166 Tagged @7 a3,
@@ -178,7 +174,7 @@ run_stateCombinerEther_flatten_9 ::
178174run_stateCombinerEther_flatten_9
179175 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
180176 =
181− E.F.runState
177+ runStates
182178 stateCombinerEther_sep_9
183179 ( Tagged @1 a9,
184180 Tagged @2 a8,
ether.cabal+8−31
@@ -27,37 +27,14 @@ source-repository head
2727library
2828
2929 exposed-modules:
30− Control.Ether.Abbr
31− Control.Ether.Implicit.Abbr
32− Control.Ether.Optic
33− Control.Monad.Trans.Ether.Handler
34− Control.Monad.Ether
35− Control.Monad.Ether.Handle
36− Control.Monad.Ether.TagAttach
37− Control.Monad.Ether.TagReplace
38− Control.Monad.Ether.Reader
39− Control.Monad.Ether.Reader.Class
40− Control.Monad.Ether.Reader.Flatten
41− Control.Monad.Ether.Writer
42− Control.Monad.Ether.Writer.Class
43− Control.Monad.Ether.State
44− Control.Monad.Ether.State.Class
45− Control.Monad.Ether.State.Lazy
46− Control.Monad.Ether.State.Strict
47− Control.Monad.Ether.State.Flatten
48− Control.Monad.Ether.State.Zoom
49− Control.Monad.Ether.Except
50− Control.Monad.Ether.Except.Class
51− Control.Monad.Ether.Implicit
52− Control.Monad.Ether.Implicit.Reader
53− Control.Monad.Ether.Implicit.Writer
54− Control.Monad.Ether.Implicit.State
55− Control.Monad.Ether.Implicit.State.Lazy
56− Control.Monad.Ether.Implicit.State.Strict
57− Control.Monad.Ether.Implicit.Except
58−
59− other-modules:
60− Control.Monad.Ether.State.Common
30+ Ether
31+ Ether.Reader
32+ Ether.State
33+ Ether.Writer
34+ Ether.Except
35+ Ether.Handler
36+ Ether.TagDispatch
37+ Ether.Internal
6138
6239 build-depends:
6340 base >=4.9 && <4.11,
src/Control/Ether/Abbr.hsdeleted−61
@@ -1,61 +0,0 @@
1−-- | Abbreviations for constraints.
2−
3−module Control.Ether.Abbr
4− ( type (-->)
5− , type (<--)
6− , type (<->)
7− , type (-!-)
8− , Ether
9− , ReifyAbbr
10− ) where
11−
12−import Data.Kind as K
13−import GHC.Exts (Constraint)
14−
15−import Control.Monad.Ether
16−
17−-- | Turns an abbreviation into an actual constraint.
18−type family ReifyAbbr (abbr :: k) :: (K.Type -> K.Type) -> Constraint
19−
20−-- | Denotes 'MonadReader'. The mnemonic is that you read values of type @r@
21−-- from the reader environment tagged by @tag@, thus the arrows points
22−-- from @tag@ to @r@.
23−data tag --> r
24−type instance ReifyAbbr (tag --> r) = MonadReader tag r
25−
26−-- | Denotes 'MonadWriter'. The mnemonic is that you write values of type @w@
27−-- to the writer accumulator tagged by @tag@, thus the arrows points
28−-- from @w@ to @tag@.
29−data tag <-- w
30−type instance ReifyAbbr (tag <-- w) = MonadWriter tag w
31−
32−-- | Denotes 'MonadState'. The mnemonic is that you can both read from and
33−-- write into the state, thus the arrow points in both directions.
34−data tag <-> s
35−type instance ReifyAbbr (tag <-> s) = MonadState tag s
36−
37−-- | Denotes 'MonadExcept'.
38−data tag -!- e
39−type instance ReifyAbbr (tag -!- e) = MonadExcept tag e
40−
41−-- | Reify a list of constraint abbreviations.
42−--
43−-- > f :: Ether '[Foo --> r, Bar <-- w, Baz <-> s, Quux -!- e] m => m a
44−--
45−-- expands into
46−--
47−-- > f :: ( MonadReader Foo r m
48−-- > , MonadWriter Bar w m
49−-- > , MonadState Baz s m
50−-- > , MonadExcept Quux e m
51−-- > ) => m a
52−
53−class U a
54−instance U a
55−
56−class (c a, d a) => (c &&& d) a
57−instance (c a, d a) => (c &&& d) a
58−
59−type family Ether (abbrs :: [K.Type]) :: (K.Type -> K.Type) -> Constraint where
60− Ether '[] = U
61− Ether (abbr ': abbrs) = ReifyAbbr abbr &&& Ether abbrs
src/Control/Ether/Implicit/Abbr.hsdeleted−23
@@ -1,23 +0,0 @@
1−-- | See "Control.Ether.Abbr".
2−
3−module Control.Ether.Implicit.Abbr (R, W, S, E) where
4−
5−import Control.Ether.Abbr (ReifyAbbr)
6−import Control.Monad.Ether.Implicit
7−
8−-- | Denotes 'MonadReader'.
9−data R r
10−type instance ReifyAbbr (R r) = MonadReader r
11−
12−-- | Denotes 'MonadWriter'.
13−data W w
14−type instance ReifyAbbr (W w) = MonadWriter w
15−
16−-- | Denotes 'MonadState'.
17−data S s
18−type instance ReifyAbbr (S s) = MonadState s
19−
20−-- | Denotes 'MonadExcept'.
21−data E e
22−type instance ReifyAbbr (E e) = MonadExcept e
23−
src/Control/Ether/Optic.hsdeleted−142
@@ -1,142 +0,0 @@
1−module Control.Ether.Optic
2− ( Tagged(..)
3− , TagsK
4− , Tags
5− , HasLens(..)
6− , LensLike
7− , Lens
8− , Lens'
9− , view
10− , over
11− , HList(..)
12− , KindOf
13− ) where
14−
15−import Control.Applicative
16−import Control.Monad
17−import Data.Functor.Identity
18−import Data.Kind as K
19−import Data.List as List
20−import Data.Tagged
21−import Data.Traversable
22−import Language.Haskell.TH
23−import Data.Coerce
24−
25−type LensLike f s t a b = (a -> f b) -> s -> f t
26−
27−type Lens s t a b = forall f. Functor f => LensLike f s t a b
28−
29−type Lens' s a = Lens s s a a
30−
31−class HasLens tag outer inner | tag outer -> inner where
32− lensOf :: Lens' outer inner
33−
34−instance HasLens a a a where
35− lensOf = id
36− {-# INLINE lensOf #-}
37−
38−view :: LensLike (Const a) s t a b -> s -> a
39−view l = coerce (l Const)
40−{-# INLINE view #-}
41−
42−over :: LensLike Identity s t a b -> (a -> b) -> s -> t
43−over = coerce
44−{-# INLINE over #-}
45−
46−data HList xs where
47− HNil :: HList '[]
48− HCons :: x -> HList xs -> HList (x ': xs)
49−
50−type KindOf (a :: k) = k
51−
52−type family TagsK (p :: K.Type) :: [K.Type]
53−type family Tags (p :: K.Type) :: HList (TagsK p)
54−
55−return []
56−
57−type instance TagsK () = '[]
58−type instance TagsK (Tagged t a) = '[KindOf t]
59−type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
60−
61−return []
62−
63−type instance Tags () = 'HNil
64−type instance Tags (Tagged t a) = 'HCons t 'HNil
65−type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
66−
67−do
68− let
69− tupCount = 62
70− names = [1..] >>= flip replicateM ['a'..'z']
71− varNames <- traverse newName (take tupCount names)
72− fmap List.concat $
73− for (List.drop 2 (List.inits varNames)) $
74− \varNames' -> do
75− let n = List.length varNames'
76− tagsInstances <- for [() | n > 2] $ \() -> do
77− tag <- newName "tag"
78− let
79− (cur:rest) = varNames'
80− tupTy = foldl AppT (ConT (tupleTypeName n))
81− ( ConT ''Tagged `AppT` VarT tag `AppT` VarT cur :
82− map VarT rest )
83− tupTy' = foldl AppT (ConT (tupleTypeName (n-1)))
84− (map VarT rest)
85− return $
86− TySynInstD ''TagsK (TySynEqn [tupTy]
87− ( PromotedConsT `AppT` (ConT ''KindOf `AppT` VarT tag) `AppT`
88− (ConT ''TagsK `AppT` tupTy') ))
89− return tagsInstances
90−do
91− let
92− tupCount = 62
93− names = [1..] >>= flip replicateM ['a'..'z']
94− varNames <- traverse newName (take tupCount names)
95− fmap List.concat $
96− for (List.drop 2 (List.inits varNames)) $
97− \varNames' -> do
98− let n = List.length varNames'
99− tagsInstances <- for [() | n > 2] $ \() -> do
100− tag <- newName "tag"
101− let
102− (cur:rest) = varNames'
103− tupTy = foldl AppT (ConT (tupleTypeName n))
104− ( ConT ''Tagged `AppT` VarT tag `AppT` VarT cur :
105− map VarT rest )
106− tupTy' = foldl AppT (ConT (tupleTypeName (n-1)))
107− (map VarT rest)
108− tagsInst =
109− TySynInstD ''Tags (TySynEqn [tupTy]
110− ( PromotedT 'HCons `AppT` VarT tag `AppT`
111− (ConT ''Tags `AppT` tupTy') ))
112− return tagsInst
113− hasLensInstances <- for [0..n-1] $ \k -> do
114− tag <- newName "tag"
115− let
116− (prev, cur:next) = List.splitAt k varNames'
117− tupTy = foldl AppT (ConT (tupleTypeName n))
118− ( map VarT prev ++
119− [ConT ''Tagged `AppT` VarT tag `AppT` VarT cur] ++
120− map VarT next )
121− cur' <- newName "x"
122− f <- newName "f"
123− return $
124− InstanceD Nothing []
125− (ConT ''HasLens `AppT` VarT tag `AppT` tupTy `AppT` VarT cur)
126− [ FunD 'lensOf
127− [ Clause
128− [VarP f, TupP
129− ( map VarP prev ++
130− [ConP 'Tagged [VarP cur]] ++
131− map VarP next )]
132− (NormalB $
133− VarE 'fmap `AppE`
134− (LamE [VarP cur']
135− (TupE
136− ( map VarE prev ++
137− [ConE 'Tagged `AppE` VarE cur'] ++
138− map VarE next ))) `AppE`
139− (VarE f `AppE` VarE cur) )
140− [] ],
141− PragmaD (InlineP 'lensOf Inline FunLike AllPhases) ]
142− return $ tagsInstances ++ hasLensInstances
src/Control/Monad/Ether.hsdeleted−13
@@ -1,13 +0,0 @@
1−-- | This module provides convenience exports of all
2−-- tagged monad classes from Ether.
3−
4−module Control.Monad.Ether (module X) where
5−
6−import Control.Monad as X
7−import Control.Monad.Fix as X
8−import Control.Monad.Ether.Reader as X
9−import Control.Monad.Ether.Writer as X
10−import Control.Monad.Ether.State as X
11−import Control.Monad.Ether.Except as X
12−import Control.Monad.Ether.TagAttach as X
13−import Control.Monad.Ether.TagReplace as X
src/Control/Monad/Ether/Except/Class.hsdeleted−29
@@ -1,29 +0,0 @@
1−-- | See "Control.Monad.Except".
2−
3−module Control.Monad.Ether.Except.Class
4− ( MonadExcept(..)
5− ) where
6−
7−import qualified Control.Monad.Trans.Lift.Catch as Lift
8−
9−-- | See 'Control.Monad.Except.MonadError'.
10−class Monad m => MonadExcept tag e m | m tag -> e where
11−
12− -- | Is used within a monadic computation to begin exception processing.
13− throw :: e -> m a
14−
15− -- | A handler function to handle previous exceptions and return to
16− -- normal execution.
17− catch :: m a -> (e -> m a) -> m a
18−
19−instance {-# OVERLAPPABLE #-}
20− ( Lift.LiftCatch t
21− , Monad (t m)
22− , MonadExcept tag e m
23− ) => MonadExcept tag e (t m) where
24−
25− throw = Lift.lift . throw @tag
26− {-# INLINE throw #-}
27−
28− catch = Lift.liftCatch (catch @tag)
29− {-# INLINE catch #-}
src/Control/Monad/Ether/Handle.hsdeleted−35
@@ -1,35 +0,0 @@
1−module Control.Monad.Ether.Handle
2− ( Handle(..)
3− , HandleSuper
4− , HandleConstraint
5− , TAGGED
6− ) where
7−
8−import Data.Kind as K
9−import GHC.Exts (Constraint)
10−
11−data TAGGED e t
12−
13−type K_Monad = K.Type -> K.Type
14−
15−type K_Trans = K_Monad -> K_Monad
16−
17−type family
18− HandleSuper
19− (eff :: keff)
20− (p :: kp)
21− (trans :: K_Trans)
22− :: Constraint
23−
24−type family
25− HandleConstraint
26− (eff :: keff)
27− (p :: kp)
28− (trans :: K_Trans) (m :: K_Monad)
29− :: Constraint
30−
31−class
32− HandleSuper eff p trans =>
33− Handle eff p (trans :: K_Trans) | eff trans -> p
34− where
35− handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
src/Control/Monad/Ether/Implicit.hsdeleted−13
@@ -1,13 +0,0 @@
1−-- | This module provides convenience exports of all
2−-- implicitly tagged monad classes from Ether.
3−
4−module Control.Monad.Ether.Implicit (module X) where
5−
6−import Control.Monad as X
7−import Control.Monad.Fix as X
8−import Control.Monad.Ether.Implicit.Reader as X
9−import Control.Monad.Ether.Implicit.Writer as X
10−import Control.Monad.Ether.Implicit.State as X
11−import Control.Monad.Ether.Implicit.Except as X
12−import Control.Monad.Ether.TagAttach as X
13−import Control.Monad.Ether.TagReplace as X
src/Control/Monad/Ether/Implicit/Except.hsdeleted−58
@@ -1,58 +0,0 @@
1−-- | See "Control.Monad.Ether.Except".
2−
3−module Control.Monad.Ether.Implicit.Except
4− (
5− -- * MonadExcept class
6− MonadExcept
7− , throw
8− , catch
9− -- * The Except monad
10− , Except
11− , runExcept
12− -- * The ExceptT monad transformer
13− , ExceptT
14− , exceptT
15− , runExceptT
16− -- * Handle functions
17− , handle
18− , handleT
19− ) where
20−
21−import qualified Control.Monad.Ether.Except as A
22−
23−-- | See 'Control.Monad.Ether.Except.MonadExcept'.
24−type MonadExcept e = A.MonadExcept e e
25−
26−-- | See 'Control.Monad.Ether.Except.throw'.
27−throw :: forall e m a . MonadExcept e m => e -> m a
28−throw = A.throw @e
29−
30−-- | See 'Control.Monad.Ether.Except.catch'.
31−catch :: forall e m a . MonadExcept e m => m a -> (e -> m a) -> m a
32−catch = A.catch @e
33−
34−-- | See 'Control.Monad.Ether.Except.Except'.
35−type Except e = A.Except e e
36−
37−-- | See 'Control.Monad.Ether.Except.runExcept'.
38−runExcept :: Except e a -> Either e a
39−runExcept = A.runExcept
40−
41−-- | See 'Control.Monad.Ether.Except.ExceptT'.
42−type ExceptT e = A.ExceptT e e
43−
44−-- | See 'Control.Monad.Ether.Except.exceptT'.
45−exceptT :: m (Either e a) -> ExceptT e m a
46−exceptT = A.exceptT
47−
48−-- | See 'Control.Monad.Ether.Except.runExceptT'.
49−runExceptT :: ExceptT e m a -> m (Either e a)
50−runExceptT = A.runExceptT
51−
52−-- | See 'Control.Monad.Ether.Except.handle'.
53−handle :: (e -> a) -> Except e a -> a
54−handle = A.handle
55−
56−-- | See 'Control.Monad.Ether.Except.handleT'.
57−handleT :: Functor m => (e -> a) -> ExceptT e m a -> m a
58−handleT = A.handleT
src/Control/Monad/Ether/Implicit/Reader.hsdeleted−57
@@ -1,57 +0,0 @@
1−-- | See "Control.Monad.Ether.Reader".
2−
3−module Control.Monad.Ether.Implicit.Reader
4− (
5− -- * MonadReader class
6− MonadReader
7− , local
8− , ask
9− , reader
10− , asks
11− -- * The Reader monad
12− , Reader
13− , runReader
14− -- * The ReaderT monad transformer
15− , ReaderT
16− , readerT
17− , runReaderT
18− ) where
19−
20−import qualified Control.Monad.Ether.Reader as A
21−
22−-- | See 'Control.Monad.Ether.Reader.ReaderT'.
23−type ReaderT r = A.ReaderT r r
24−
25−-- | See 'Control.Monad.Ether.Reader.readerT'.
26−readerT :: (r -> m a) -> ReaderT r m a
27−readerT = A.readerT
28−
29−-- | See 'Control.Monad.Ether.Reader.runReaderT'.
30−runReaderT :: ReaderT r m a -> r -> m a
31−runReaderT = A.runReaderT
32−
33−-- | See 'Control.Monad.Ether.Reader.Reader'.
34−type Reader r = A.Reader r r
35−
36−-- | See 'Control.Monad.Ether.Reader.runReader'.
37−runReader :: Reader r a -> r -> a
38−runReader = A.runReader
39−
40−-- | See 'Control.Monad.Ether.Reader.MonadReader'.
41−type MonadReader r = A.MonadReader r r
42−
43−-- | See 'Control.Monad.Ether.Reader.local'.
44−local :: forall r m a . MonadReader r m => (r -> r) -> m a -> m a
45−local = A.local @r
46−
47−-- | See 'Control.Monad.Ether.Reader.ask'.
48−ask :: forall r m . MonadReader r m => m r
49−ask = A.ask @r
50−
51−-- | See 'Control.Monad.Ether.Reader.reader'.
52−reader :: forall r m a . MonadReader r m => (r -> a) -> m a
53−reader = A.reader @r
54−
55−-- | See 'Control.Monad.Ether.Reader.asks'.
56−asks :: forall r m a . MonadReader r m => (r -> a) -> m a
57−asks = A.asks @r
src/Control/Monad/Ether/Implicit/State.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- | See "Control.Monad.Ether.State".
2−
3−module Control.Monad.Ether.Implicit.State
4− ( module Control.Monad.Ether.Implicit.State.Lazy
5− ) where
6−
7−import Control.Monad.Ether.Implicit.State.Lazy
src/Control/Monad/Ether/Implicit/State/Lazy.hsdeleted−82
@@ -1,82 +0,0 @@
1−-- | See "Control.Monad.Ether.State.Lazy".
2−
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− ) where
24−
25−import qualified Control.Monad.Ether.State.Lazy as A
26−
27−-- | See 'Control.Monad.Ether.State.Lazy.StateT'.
28−type StateT s = A.StateT s s
29−
30−-- | See 'Control.Monad.Ether.State.Lazy.stateT'.
31−stateT :: (s -> m (a, s)) -> StateT s m a
32−stateT = A.stateT
33−
34−-- | See 'Control.Monad.Ether.State.Lazy.runStateT'.
35−runStateT :: StateT s m a -> s -> m (a, s)
36−runStateT = A.runStateT
37−
38−-- | See 'Control.Monad.Ether.State.Lazy.runState'.
39−runState :: State s a -> s -> (a, s)
40−runState = A.runState
41−
42−-- | See 'Control.Monad.Ether.State.Lazy.evalStateT'.
43−evalStateT :: Monad m => StateT s m a -> s -> m a
44−evalStateT = A.evalStateT
45−
46−-- | See 'Control.Monad.Ether.State.Lazy.State'.
47−type State s = A.State s s
48−
49−-- | See 'Control.Monad.Ether.State.Lazy.evalState'.
50−evalState :: State s a -> s -> a
51−evalState = A.evalState
52−
53−-- | See 'Control.Monad.Ether.State.Lazy.execStateT'.
54−execStateT :: Monad m => StateT s m a -> s -> m s
55−execStateT = A.execStateT
56−
57−-- | See 'Control.Monad.Ether.State.Lazy.execState'.
58−execState :: State s a -> s -> s
59−execState = A.execState
60−
61−-- | See 'Control.Monad.Ether.State.Lazy.MonadState'.
62−type MonadState s = A.MonadState s s
63−
64−-- | See 'Control.Monad.Ether.State.Lazy.get'.
65−get :: forall s m . MonadState s m => m s
66−get = A.get @s
67−
68−-- | See 'Control.Monad.Ether.State.Lazy.gets'.
69−gets :: forall s m a . MonadState s m => (s -> a) -> m a
70−gets = A.gets @s
71−
72−-- | See 'Control.Monad.Ether.State.Lazy.put'.
73−put :: forall s m . MonadState s m => s -> m ()
74−put = A.put @s
75−
76−-- | See 'Control.Monad.Ether.State.Lazy.state'.
77−state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
78−state = A.state @s
79−
80−-- | See 'Control.Monad.Ether.State.Lazy.modify'.
81−modify :: forall s m . MonadState s m => (s -> s) -> m ()
82−modify = A.modify @s
src/Control/Monad/Ether/Implicit/State/Strict.hsdeleted−82
@@ -1,82 +0,0 @@
1−-- | See "Control.Monad.Ether.State.Strict".
2−
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− ) where
24−
25−import qualified Control.Monad.Ether.State.Strict as A
26−
27−-- | See 'Control.Monad.Ether.State.Strict.StateT'.
28−type StateT s = A.StateT s s
29−
30−-- | See 'Control.Monad.Ether.State.Strict.stateT'.
31−stateT :: (s -> m (a, s)) -> StateT s m a
32−stateT = A.stateT
33−
34−-- | See 'Control.Monad.Ether.State.Strict.runStateT'.
35−runStateT :: StateT s m a -> s -> m (a, s)
36−runStateT = A.runStateT
37−
38−-- | See 'Control.Monad.Ether.State.Strict.runState'.
39−runState :: State s a -> s -> (a, s)
40−runState = A.runState
41−
42−-- | See 'Control.Monad.Ether.State.Strict.evalStateT'.
43−evalStateT :: Monad m => StateT s m a -> s -> m a
44−evalStateT = A.evalStateT
45−
46−-- | See 'Control.Monad.Ether.State.Strict.State'.
47−type State s = A.State s s
48−
49−-- | See 'Control.Monad.Ether.State.Strict.evalState'.
50−evalState :: State s a -> s -> a
51−evalState = A.evalState
52−
53−-- | See 'Control.Monad.Ether.State.Strict.execStateT'.
54−execStateT :: Monad m => StateT s m a -> s -> m s
55−execStateT = A.execStateT
56−
57−-- | See 'Control.Monad.Ether.State.Strict.execState'.
58−execState :: State s a -> s -> s
59−execState = A.execState
60−
61−-- | See 'Control.Monad.Ether.State.Strict.MonadState'.
62−type MonadState s = A.MonadState s s
63−
64−-- | See 'Control.Monad.Ether.State.Strict.get'.
65−get :: forall s m . MonadState s m => m s
66−get = A.get @s
67−
68−-- | See 'Control.Monad.Ether.State.Strict.gets'.
69−gets :: forall s m a . MonadState s m => (s -> a) -> m a
70−gets = A.gets @s
71−
72−-- | See 'Control.Monad.Ether.State.Strict.put'.
73−put :: forall s m . MonadState s m => s -> m ()
74−put = A.put @s
75−
76−-- | See 'Control.Monad.Ether.State.Strict.state'.
77−state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
78−state = A.state @s
79−
80−-- | See 'Control.Monad.Ether.State.Strict.modify'.
81−modify :: forall s m . MonadState s m => (s -> s) -> m ()
82−modify = A.modify @s
src/Control/Monad/Ether/Implicit/Writer.hsdeleted−77
@@ -1,77 +0,0 @@
1−-- | See "Control.Monad.Ether.Writer".
2−
3−module Control.Monad.Ether.Implicit.Writer
4− (
5− -- * MonadWriter class
6− MonadWriter
7− , writer
8− , tell
9− , listen
10− , pass
11− , listens
12− , censor
13− -- * The Writer monad
14− , Writer
15− , runWriter
16− , execWriter
17− -- * The WriterT monad transformer
18− , WriterT
19− , writerT
20− , runWriterT
21− , execWriterT
22− ) where
23−
24−import qualified Control.Monad.Ether.Writer as A
25−
26−-- | See 'Control.Monad.Ether.Writer.MonadWriter'.
27−type MonadWriter w = A.MonadWriter w w
28−
29−-- | See 'Control.Monad.Ether.Writer.writer'.
30−writer :: forall w m a . MonadWriter w m => (a, w) -> m a
31−writer = A.writer @w
32−
33−-- | See 'Control.Monad.Ether.Writer.tell'.
34−tell :: forall w m . MonadWriter w m => w -> m ()
35−tell = A.tell @w
36−
37−-- | See 'Control.Monad.Ether.Writer.listen'.
38−listen :: forall w m a . MonadWriter w m => m a -> m (a, w)
39−listen = A.listen @w
40−
41−-- | See 'Control.Monad.Ether.Writer.pass'.
42−pass :: forall w m a . MonadWriter w m => m (a, w -> w) -> m a
43−pass = A.pass @w
44−
45−-- | See 'Control.Monad.Ether.Writer.listens'.
46−listens :: forall w m a b . MonadWriter w m => (w -> b) -> m a -> m (a, b)
47−listens = A.listens @w
48−
49−-- | See 'Control.Monad.Ether.Writer.censor'.
50−censor :: forall w m a . MonadWriter w m => (w -> w) -> m a -> m a
51−censor = A.censor @w
52−
53−-- | See 'Control.Monad.Ether.Writer.Writer'.
54−type Writer w = A.Writer w w
55−
56−-- | See 'Control.Monad.Ether.Writer.runWriter'.
57−runWriter :: Writer w a -> (a, w)
58−runWriter = A.runWriter
59−
60−-- | See 'Control.Monad.Ether.Writer.execWriter'.
61−execWriter :: Writer w a -> w
62−execWriter = A.execWriter
63−
64−-- | See 'Control.Monad.Ether.Writer.WriterT'.
65−type WriterT w = A.WriterT w w
66−
67−-- | See 'Control.Monad.Ether.Writer.writerT'.
68−writerT :: m (a, w) -> WriterT w m a
69−writerT = A.writerT
70−
71−-- | See 'Control.Monad.Ether.Writer.runWriterT'.
72−runWriterT :: WriterT w m a -> m (a, w)
73−runWriterT = A.runWriterT
74−
75−-- | See 'Control.Monad.Ether.Writer.execWriterT'.
76−execWriterT :: Monad m => WriterT w m a -> m w
77−execWriterT = A.execWriterT
src/Control/Monad/Ether/Reader.hsdeleted−128
@@ -1,128 +0,0 @@
1−-- | See "Control.Monad.Reader".
2−
3−module Control.Monad.Ether.Reader
4− (
5− -- * MonadReader class
6− MonadReader
7− , ask
8− , local
9− , reader
10− , asks
11− -- * The Reader monad
12− , Reader
13− , runReader
14− -- * The ReaderT monad transformer
15− , ReaderT
16− , readerT
17− , runReaderT
18− -- *
19− , READER
20− ) where
21−
22−import Control.Monad.Ether.Handle
23−import Control.Monad.Ether.Reader.Class
24−import Control.Ether.Optic
25−import Control.Monad.Trans.Ether.Handler
26−import Control.Monad.Trans.Lift.Local (Local)
27−import qualified Control.Monad.Reader as T
28−import Data.Functor.Identity
29−import Data.Coerce
30−
31−-- | Retrieves a function of the current environment.
32−asks
33− :: forall tag r m a
34− . MonadReader tag r m
35− => (r -> a)
36− -- ^ The selector function to apply to the environment.
37− -> m a
38−asks = reader @tag
39−{-# INLINE asks #-}
40−
41−-- | Encode type-level information for 'ReaderT'.
42−data READER
43−
44−-- | The parameterizable reader monad.
45−--
46−-- Computations are functions of a shared environment.
47−--
48−-- The 'return' function ignores the environment, while '>>=' passes
49−-- the inherited environment to both subcomputations.
50−type Reader tag r = ReaderT tag r Identity
51−
52−-- | The reader monad transformer,
53−-- which adds a read-only environment to the given monad.
54−--
55−-- The 'return' function ignores the environment, while '>>=' passes
56−-- the inherited environment to both subcomputations.
57−type ReaderT tag r = Handler (TAGGED READER tag) (T.ReaderT r)
58−
59−-- | Constructor for computations in the reader monad transformer.
60−readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
61−readerT = coerce (T.ReaderT @r @m @a)
62−{-# INLINE readerT #-}
63−
64−-- | Runs a 'ReaderT' with the given environment
65−-- and returns the final value.
66−runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
67−runReaderT = coerce (T.runReaderT @r @_ @m @a)
68−{-# INLINE runReaderT #-}
69−
70−-- | Runs a 'ReaderT' with the given environment
71−-- and returns the final value.
72−runReader :: forall tag r a . Reader tag r a -> r -> a
73−runReader = coerce (T.runReader @r @a)
74−{-# INLINE runReader #-}
75−
76−type instance HandleSuper READER r trans = ()
77−type instance HandleConstraint READER r trans m =
78− T.MonadReader r (trans m)
79−
80−instance Handle READER r (T.ReaderT r) where
81− handling r = r
82− {-# INLINE handling #-}
83−
84−instance
85− ( Handle READER r trans
86− , Monad m, Monad (trans m)
87− ) => MonadReader tag r (Handler (TAGGED READER tag) trans m)
88− where
89−
90− ask =
91− handling @READER @r @trans @m $
92− coerce (T.ask @r @(trans m))
93− {-# INLINE ask #-}
94−
95− local =
96− handling @READER @r @trans @m $
97− coerce (T.local @r @(trans m) @a) ::
98− forall eff a . Local r (Handler eff trans m) a
99− {-# INLINE local #-}
100−
101− reader =
102− handling @READER @r @trans @m $
103− coerce (T.reader @r @(trans m) @a) ::
104− forall eff a . (r -> a) -> Handler eff trans m a
105− {-# INLINE reader #-}
106−
107−instance
108− ( HasLens tag payload r
109− , Handle READER payload trans
110− , Monad m, Monad (trans m)
111− ) => MonadReader tag r (Handler (TAGGED READER tag ': effs) trans m)
112− where
113−
114− ask =
115− handling @READER @payload @trans @m $
116− (coerce :: forall eff a .
117− trans m a ->
118− Handler eff trans m a)
119− (T.asks (view (lensOf @tag @payload @r)))
120− {-# INLINE ask #-}
121−
122− local f =
123− handling @READER @payload @trans @m $
124− (coerce :: forall eff a .
125− (trans m a -> trans m a) ->
126− (Handler eff trans m a -> Handler eff trans m a))
127− (T.local (over (lensOf @tag @payload @r) f))
128− {-# INLINE local #-}
src/Control/Monad/Ether/Reader/Class.hsdeleted−77
@@ -1,77 +0,0 @@
1−-- | See "Control.Monad.Reader.Class".
2−
3−module Control.Monad.Ether.Reader.Class
4− ( MonadReader(..)
5− ) where
6−
7−import Data.Kind as K
8−import Control.Monad.Trans.Ether.Handler
9−import qualified Control.Monad.Trans.Lift.Local as Lift
10−import Data.Coerce
11−
12−-- | See 'Control.Monad.Reader.MonadReader'.
13−class Monad m => MonadReader tag r m | m tag -> r where
14−
15− {-# MINIMAL (ask | reader), local #-}
16−
17− -- | Retrieves the monad environment.
18− ask :: m r
19− ask = reader @tag id
20−
21− -- | Executes a computation in a modified environment.
22− local
23− :: (r -> r)
24− -- ^ The function to modify the environment.
25− -> m a
26− -- ^ @Reader@ to run in the modified environment.
27− -> m a
28−
29− -- | Retrieves a function of the current environment.
30− reader
31− :: (r -> a)
32− -- ^ The selector function to apply to the environment.
33− -> m a
34− reader f = fmap f (ask @tag)
35−
36−instance {-# OVERLAPPABLE #-}
37− ( Lift.LiftLocal t
38− , Monad (t m)
39− , MonadReader tag r m
40− ) => MonadReader tag r (t m)
41− where
42−
43− ask = Lift.lift (ask @tag)
44− {-# INLINE ask #-}
45−
46− local = Lift.liftLocal (ask @tag) (local @tag)
47− {-# INLINE local #-}
48−
49− reader = Lift.lift . reader @tag
50− {-# INLINE reader #-}
51−
52−instance {-# OVERLAPPABLE #-}
53− ( Monad (trans m)
54− , MonadReader tag r (Handler effs trans m)
55− ) => MonadReader tag r (Handler (eff ': effs) trans (m :: K.Type -> K.Type))
56− where
57−
58− ask =
59− (coerce ::
60− Handler effs trans m r ->
61− Handler (eff ': effs) trans m r)
62− (ask @tag)
63− {-# INLINE ask #-}
64−
65− local =
66− (coerce :: forall a .
67− Lift.Local r (Handler effs trans m) a ->
68− Lift.Local r (Handler (eff ': effs) trans m) a)
69− (local @tag)
70− {-# INLINE local #-}
71−
72− reader =
73− (coerce :: forall a .
74− ((r -> a) -> Handler effs trans m a) ->
75− ((r -> a) -> Handler (eff ': effs) trans m a))
76− (reader @tag)
77− {-# INLINE reader #-}
src/Control/Monad/Ether/Reader/Flatten.hsdeleted−29
@@ -1,29 +0,0 @@
1−module Control.Monad.Ether.Reader.Flatten
2− ( ReaderT
3− , runReaderT
4− , Reader
5− , runReader
6− ) where
7−
8−import Control.Ether.Optic
9−import Control.Monad.Ether.Handle
10−import Control.Monad.Ether.Reader (READER)
11−import qualified Control.Monad.Reader as T
12−import Control.Monad.Trans.Ether.Handler
13−import Data.Coerce
14−import Data.Functor.Identity
15−import Data.Kind
16−
17−type family READERS (ts :: HList xs) :: [Type] where
18− READERS 'HNil = '[]
19− READERS ('HCons t ts) = TAGGED READER t ': READERS ts
20−
21−type ReaderT r = Handler (READERS (Tags r)) (T.ReaderT r)
22−
23−type Reader r = ReaderT r Identity
24−
25−runReaderT :: forall p m a . ReaderT p m a -> p -> m a
26−runReaderT = coerce (T.runReaderT @p @_ @m @a)
27−
28−runReader :: forall p a . Reader p a -> p -> a
29−runReader = coerce (T.runReader @p @a)
src/Control/Monad/Ether/State.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- | See "Control.Monad.State".
2−
3−module Control.Monad.Ether.State
4− ( module Control.Monad.Ether.State.Lazy
5− ) where
6−
7−import Control.Monad.Ether.State.Lazy
src/Control/Monad/Ether/State/Class.hsdeleted−74
@@ -1,74 +0,0 @@
1−-- | See "Control.Monad.State.Class".
2−
3−module Control.Monad.Ether.State.Class
4− ( MonadState(..)
5− ) where
6−
7−import Data.Kind as K
8−import Control.Monad.Trans.Ether.Handler
9−import qualified Control.Monad.Trans as Lift
10−import Data.Coerce
11−
12−-- | See 'Control.Monad.State.MonadState'.
13−class Monad m => MonadState tag s m | m tag -> s where
14−
15− {-# MINIMAL state | get, put #-}
16−
17− -- | Return the state from the internals of the monad.
18− get :: m s
19− get = state @tag (\s -> (s, s))
20−
21− -- | Replace the state inside the monad.
22− put :: s -> m ()
23− put s = state @tag (\_ -> ((), s))
24−
25− -- | Embed a simple state action into the monad.
26− state :: (s -> (a, s)) -> m a
27− state f = do
28− s <- get @tag
29− let ~(a, s') = f s
30− put @tag s'
31− return a
32−
33−instance {-# OVERLAPPABLE #-}
34− ( Lift.MonadTrans t
35− , Monad (t m)
36− , MonadState tag s m
37− ) => MonadState tag s (t m)
38− where
39−
40− get = Lift.lift (get @tag)
41− {-# INLINE get #-}
42−
43− put = Lift.lift . put @tag
44− {-# INLINE put #-}
45−
46− state = Lift.lift . state @tag
47− {-# INLINE state #-}
48−
49−instance {-# OVERLAPPABLE #-}
50− ( Monad (trans m)
51− , MonadState tag s (Handler effs trans m)
52− ) => MonadState tag s (Handler (eff ': effs) trans (m :: K.Type -> K.Type))
53− where
54−
55− get =
56− (coerce ::
57− Handler effs trans m s ->
58− Handler (eff ': effs) trans m s)
59− (get @tag)
60− {-# INLINE get #-}
61−
62− put =
63− (coerce ::
64− (s -> Handler effs trans m ()) ->
65− (s -> Handler (eff ': effs) trans m ()))
66− (put @tag)
67− {-# INLINE put #-}
68−
69− state =
70− (coerce :: forall a .
71− ((s -> (a, s)) -> Handler effs trans m a) ->
72− ((s -> (a, s)) -> Handler (eff ': effs) trans m a))
73− (state @tag)
74− {-# INLINE state #-}
src/Control/Monad/Ether/State/Common.hsdeleted−90
@@ -1,90 +0,0 @@
1−module Control.Monad.Ether.State.Common
2− ( MonadState
3− , get
4− , put
5− , state
6− , modify
7− , gets
8− , STATE
9− ) where
10−
11−import Control.Ether.Optic
12−import Control.Monad.Ether.Handle
13−import Control.Monad.Ether.State.Class
14−import qualified Control.Monad.State as T
15−import Control.Monad.Trans.Ether.Handler
16−import Data.Coerce
17−
18−-- | Encode type-level information for 'StateT'.
19−data STATE
20−
21−-- | Modifies the state inside a state monad.
22−modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
23−modify f = state @tag (\s -> ((), f s))
24−{-# INLINABLE modify #-}
25−
26−-- | Gets specific component of the state, using a projection function supplied.
27−gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
28−gets f = fmap f (get @tag)
29−{-# INLINABLE gets #-}
30−
31−type instance HandleSuper STATE s trans = ()
32−type instance HandleConstraint STATE s trans m =
33− T.MonadState s (trans m)
34−
35−instance Handle STATE s (T.StateT s) where
36− handling r = r
37− {-# INLINE handling #-}
38−
39−instance
40− ( Handle STATE s trans
41− , Monad m, Monad (trans m)
42− ) => MonadState tag s (Handler (TAGGED STATE tag) trans m)
43− where
44−
45− get =
46− handling @STATE @s @trans @m $
47− coerce (T.get @s @(trans m))
48− {-# INLINE get #-}
49−
50− put =
51− handling @STATE @s @trans @m $
52− coerce (T.put @s @(trans m))
53− {-# INLINE put #-}
54−
55− state =
56− handling @STATE @s @trans @m $
57− coerce (T.state @s @(trans m) @a) ::
58− forall eff a . (s -> (a, s)) -> Handler eff trans m a
59− {-# INLINE state #-}
60−
61−instance
62− ( HasLens tag payload s
63− , Handle STATE payload trans
64− , Monad m, Monad (trans m)
65− ) => MonadState tag s (Handler (TAGGED STATE tag ': effs) trans m)
66− where
67−
68− get =
69− handling @STATE @payload @trans @m $
70− (coerce :: forall eff a .
71− trans m a ->
72− Handler eff trans m a)
73− (T.gets (view (lensOf @tag @payload @s)))
74− {-# INLINE get #-}
75−
76− put s =
77− handling @STATE @payload @trans @m $
78− (coerce :: forall eff a .
79− trans m a ->
80− Handler eff trans m a)
81− (T.modify (over (lensOf @tag @payload @s) (const s)))
82− {-# INLINE put #-}
83−
84− state f =
85− handling @STATE @payload @trans @m $
86− (coerce :: forall eff a .
87− trans m a ->
88− Handler eff trans m a)
89− (T.state (lensOf @tag @payload @s f))
90− {-# INLINE state #-}
src/Control/Monad/Ether/State/Flatten.hsdeleted−29
@@ -1,29 +0,0 @@
1−module Control.Monad.Ether.State.Flatten
2− ( StateT
3− , runStateT
4− , State
5− , runState
6− ) where
7−
8−import Control.Ether.Optic
9−import Control.Monad.Ether.Handle
10−import Control.Monad.Ether.State (STATE)
11−import qualified Control.Monad.State as T
12−import Control.Monad.Trans.Ether.Handler
13−import Data.Coerce
14−import Data.Functor.Identity
15−import Data.Kind
16−
17−type family STATES (ts :: HList xs) :: [Type] where
18− STATES 'HNil = '[]
19− STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
20−
21−type StateT s = Handler (STATES (Tags s)) (T.StateT s)
22−
23−type State s = StateT s Identity
24−
25−runStateT :: forall p m a . StateT p m a -> p -> m (a, p)
26−runStateT = coerce (T.runStateT @p @m @a)
27−
28−runState :: forall p a . State p a -> p -> (a, p)
29−runState = coerce (T.runState @p @a)
src/Control/Monad/Ether/State/Lazy.hsdeleted−87
@@ -1,87 +0,0 @@
1−-- | See "Control.Monad.State.Lazy".
2−
3−module Control.Monad.Ether.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− -- *
24− , STATE
25− ) where
26−
27−import Control.Monad.Ether.Handle
28−import Control.Monad.Ether.State.Common
29−import qualified Control.Monad.Trans.Ether.Handler as D
30−import qualified Control.Monad.Trans.State.Lazy as T
31−import Data.Functor.Identity
32−import Data.Coerce
33−
34−-- | The parametrizable state monad.
35−--
36−-- Computations have access to a mutable state.
37−--
38−-- The 'return' function leaves the state unchanged, while '>>=' uses
39−-- the final state of the first computation as the initial state of the second.
40−type State tag r = StateT tag r Identity
41−
42−-- | The state monad transformer.
43−--
44−-- The 'return' function leaves the state unchanged, while '>>=' uses
45−-- the final state of the first computation as the initial state of the second.
46−type StateT tag s = D.Handler (TAGGED STATE tag) (T.StateT s)
47−
48−-- | Constructor for computations in the state monad transformer.
49−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
50−stateT = coerce (T.StateT @s @m @a)
51−{-# INLINE stateT #-}
52−
53−-- | Runs a 'StateT' with the given initial state
54−-- and returns both the final value and the final state.
55−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
56−runStateT = coerce (T.runStateT @s @m @a)
57−{-# INLINE runStateT #-}
58−
59−-- | Runs a 'StateT' with the given initial state
60−-- and returns the final value, discarding the final state.
61−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
62−evalStateT = coerce (T.evalStateT @m @s @a)
63−{-# INLINE evalStateT #-}
64−
65−-- | Runs a 'StateT' with the given initial state
66−-- and returns the final state, discarding the final value.
67−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
68−execStateT = coerce (T.execStateT @m @s @a)
69−{-# INLINE execStateT #-}
70−
71−-- | Runs a 'State' with the given initial state
72−-- and returns both the final value and the final state.
73−runState :: forall tag s a . State tag s a -> s -> (a, s)
74−runState = coerce (T.runState @s @a)
75−{-# INLINE runState #-}
76−
77−-- | Runs a 'State' with the given initial state
78−-- and returns the final value, discarding the final state.
79−evalState :: forall tag s a . State tag s a -> s -> a
80−evalState = coerce (T.evalState @s @a)
81−{-# INLINE evalState #-}
82−
83−-- | Runs a 'State' with the given initial state
84−-- and returns the final state, discarding the final value.
85−execState :: forall tag s a . State tag s a -> s -> s
86−execState = coerce (T.execState @s @a)
87−{-# INLINE execState #-}
src/Control/Monad/Ether/State/Strict.hsdeleted−87
@@ -1,87 +0,0 @@
1−-- | See "Control.Monad.State.Strict".
2−
3−module Control.Monad.Ether.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− -- *
24− , STATE
25− ) where
26−
27−import Control.Monad.Ether.Handle
28−import Control.Monad.Ether.State.Common
29−import qualified Control.Monad.Trans.Ether.Handler as D
30−import qualified Control.Monad.Trans.State.Strict as T
31−import Data.Functor.Identity
32−import Data.Coerce
33−
34−-- | The parametrizable state monad.
35−--
36−-- Computations have access to a mutable state.
37−--
38−-- The 'return' function leaves the state unchanged, while '>>=' uses
39−-- the final state of the first computation as the initial state of the second.
40−type State tag r = StateT tag r Identity
41−
42−-- | The state monad transformer.
43−--
44−-- The 'return' function leaves the state unchanged, while '>>=' uses
45−-- the final state of the first computation as the initial state of the second.
46−type StateT tag s = D.Handler (TAGGED STATE tag) (T.StateT s)
47−
48−-- | Constructor for computations in the state monad transformer.
49−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
50−stateT = coerce (T.StateT @s @m @a)
51−{-# INLINE stateT #-}
52−
53−-- | Runs a 'StateT' with the given initial state
54−-- and returns both the final value and the final state.
55−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
56−runStateT = coerce (T.runStateT @s @m @a)
57−{-# INLINE runStateT #-}
58−
59−-- | Runs a 'StateT' with the given initial state
60−-- and returns the final value, discarding the final state.
61−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
62−evalStateT = coerce (T.evalStateT @m @s @a)
63−{-# INLINE evalStateT #-}
64−
65−-- | Runs a 'StateT' with the given initial state
66−-- and returns the final state, discarding the final value.
67−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
68−execStateT = coerce (T.execStateT @m @s @a)
69−{-# INLINE execStateT #-}
70−
71−-- | Runs a 'State' with the given initial state
72−-- and returns both the final value and the final state.
73−runState :: forall tag s a . State tag s a -> s -> (a, s)
74−runState = coerce (T.runState @s @a)
75−{-# INLINE runState #-}
76−
77−-- | Runs a 'State' with the given initial state
78−-- and returns the final value, discarding the final state.
79−evalState :: forall tag s a . State tag s a -> s -> a
80−evalState = coerce (T.evalState @s @a)
81−{-# INLINE evalState #-}
82−
83−-- | Runs a 'State' with the given initial state
84−-- and returns the final state, discarding the final value.
85−execState :: forall tag s a . State tag s a -> s -> s
86−execState = coerce (T.execState @s @a)
87−{-# INLINE execState #-}
src/Control/Monad/Ether/State/Zoom.hsdeleted−48
@@ -1,48 +0,0 @@
1−{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
2−
3−module Control.Monad.Ether.State.Zoom
4− ( TAG_ZOOM
5− , TagZoomT
6− , tagZoom
7− ) where
8−
9−import Control.Ether.Optic
10−import Data.Kind as K
11−import Data.Reflection
12−import Control.Monad.Trans.Ether.Handler
13−import Control.Monad.Trans.Identity
14−import Control.Monad.Ether.State.Class
15−import Data.Proxy
16−import Data.Coerce
17−
18−-- | Encode type-level information for 'tagZoom'.
19−data TAG_ZOOM t z
20−
21−type TagZoomT t (z :: K.Type) = Handler (TAG_ZOOM t z) IdentityT
22−
23−newtype ReifiedLens s t a b = Lens (Lens s t a b)
24−
25−type ReifiedLens' s a = ReifiedLens s s a a
26−
27−-- | Zoom into a part of a state using a lens.
28−tagZoom
29− :: forall tag sOuter sInner m a
30− . Lens' sOuter sInner
31− -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => TagZoomT tag z m a)
32− -> m a
33−tagZoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
34−
35−instance
36− ( MonadState tag sOuter m
37− , Reifies z (ReifiedLens' sOuter sInner)
38− , trans ~ IdentityT
39− ) => MonadState tag sInner (Handler (TAG_ZOOM tag z) trans m)
40− where
41− state =
42− (coerce :: forall eff r a .
43− (r -> m a) ->
44− (r -> Handler eff trans m a))
45− (state @tag . l)
46− where
47− Lens l = reflect (Proxy :: Proxy z)
48− {-# INLINE state #-}
src/Control/Monad/Ether/TagAttach.hsdeleted−66
@@ -1,66 +0,0 @@
1−module Control.Monad.Ether.TagAttach
2− ( TAG_ATTACH
3− , TagAttachT
4− , tagAttach
5− ) where
6−
7−import Control.Monad.Trans.Identity
8−
9−import Control.Monad.Ether.Reader.Class
10−import Control.Monad.Ether.State.Class
11−import Control.Monad.Ether.Except.Class
12−import Control.Monad.Ether.Writer.Class
13−
14−import Control.Monad.Ether.Reader as A
15−import Control.Monad.Ether.State.Common as A
16−import Control.Monad.Ether.Except as A
17−import Control.Monad.Ether.Writer as A
18−
19−import qualified Control.Monad.Reader.Class as Class
20−import qualified Control.Monad.State.Class as Class
21−import qualified Control.Monad.Writer.Class as Class
22−import qualified Control.Monad.Error.Class as Class
23−
24−import Control.Monad.Trans.Ether.Handler
25−
26−import Data.Coerce
27−
28−-- | Encode type-level information for 'tagAttach'.
29−data TAG_ATTACH t
30−
31−type TagAttachT t = Handler (TAG_ATTACH t) IdentityT
32−
33−-- | Attach a tag to untagged transformers.
34−tagAttach :: forall tag m a . TagAttachT tag m a -> m a
35−tagAttach = coerce (runIdentityT @_ @m @a)
36−{-# INLINE tagAttach #-}
37−
38−instance
39− ( MonadReader tag r m, trans ~ IdentityT
40− ) => Class.MonadReader r (Handler (TAG_ATTACH tag) trans m)
41− where
42− ask = A.ask @tag
43− local = A.local @tag
44−
45−instance
46− ( MonadState tag s m, trans ~ IdentityT
47− ) => Class.MonadState s (Handler (TAG_ATTACH tag) trans m)
48− where
49− get = A.get @tag
50− put = A.put @tag
51−
52−instance
53− ( MonadExcept tag e m, trans ~ IdentityT
54− ) => Class.MonadError e (Handler (TAG_ATTACH tag) trans m)
55− where
56− throwError = A.throw @tag
57− catchError = A.catch @tag
58−
59−instance
60− ( MonadWriter tag w m, trans ~ IdentityT
61− ) => Class.MonadWriter w (Handler (TAG_ATTACH tag) trans m)
62− where
63− writer = A.writer @tag
64− tell = A.tell @tag
65− listen = A.listen @tag
66− pass = A.pass @tag
src/Control/Monad/Ether/TagReplace.hsdeleted−61
@@ -1,61 +0,0 @@
1−module Control.Monad.Ether.TagReplace
2− ( TAG_REPLACE
3− , TagReplaceT
4− , tagReplace
5− ) where
6−
7−import Control.Monad.Trans.Identity
8−
9−import Control.Monad.Ether.Reader.Class
10−import Control.Monad.Ether.State.Class
11−import Control.Monad.Ether.Except.Class
12−import Control.Monad.Ether.Writer.Class
13−
14−import Control.Monad.Ether.Reader as A
15−import Control.Monad.Ether.State.Common as A
16−import Control.Monad.Ether.Except as A
17−import Control.Monad.Ether.Writer as A
18−
19−import Control.Monad.Trans.Ether.Handler
20−
21−import Data.Coerce
22−
23−-- | Encode type-level information for 'tagReplace'.
24−data TAG_REPLACE tOld tNew
25−
26−type TagReplaceT tOld tNew = Handler (TAG_REPLACE tOld tNew) IdentityT
27−
28−-- | Replace a tag with another tag.
29−tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
30−tagReplace = coerce (runIdentityT @_ @m @a)
31−{-# INLINE tagReplace #-}
32−
33−instance
34− ( MonadReader tNew r m, trans ~ IdentityT
35− ) => MonadReader tOld r (Handler (TAG_REPLACE tOld tNew) trans m)
36− where
37− ask = A.ask @tNew
38− local = A.local @tNew
39−
40−instance
41− ( MonadState tNew s m, trans ~ IdentityT
42− ) => MonadState tOld s (Handler (TAG_REPLACE tOld tNew) trans m)
43− where
44− get = A.get @tNew
45− put = A.put @tNew
46−
47−instance
48− ( MonadExcept tNew e m, trans ~ IdentityT
49− ) => MonadExcept tOld e (Handler (TAG_REPLACE tOld tNew) trans m)
50− where
51− throw = A.throw @tNew
52− catch = A.catch @tNew
53−
54−instance
55− ( MonadWriter tNew w m, trans ~ IdentityT
56− ) => MonadWriter tOld w (Handler (TAG_REPLACE tOld tNew) trans m)
57− where
58− writer = A.writer @tNew
59− tell = A.tell @tNew
60− listen = A.listen @tNew
61− pass = A.pass @tNew
src/Control/Monad/Ether/Writer/Class.hsdeleted−49
@@ -1,49 +0,0 @@
1−-- | See "Control.Monad.Writer.Class".
2−
3−module Control.Monad.Ether.Writer.Class
4− ( MonadWriter(..)
5− ) where
6−
7−import qualified Control.Monad.Trans.Lift.Listen as Lift
8−import qualified Control.Monad.Trans.Lift.Pass as Lift
9−
10−-- | See 'Control.Monad.Writer.MonadWriter'.
11−class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
12−
13− {-# MINIMAL (writer | tell), listen, pass #-}
14−
15− -- | Embed a simple writer action.
16− writer :: (a, w) -> m a
17− writer ~(a, w) = a <$ tell @tag w
18−
19− -- | Append a value to the accumulator within the monad.
20− tell :: w -> m ()
21− tell w = writer @tag ((),w)
22−
23− -- | Execute an action and add its accumulator
24− -- to the value of the computation.
25− listen :: m a -> m (a, w)
26−
27− -- | Execute an action which returns a value and a function,
28− -- and return the value, applying the function to the accumulator.
29− pass :: m (a, w -> w) -> m a
30−
31−instance {-# OVERLAPPABLE #-}
32− ( Lift.LiftListen t
33− , Lift.LiftPass t
34− , Monad (t m)
35− , MonadWriter tag w m
36− , Monoid w
37− ) => MonadWriter tag w (t m) where
38−
39− writer = Lift.lift . writer @tag
40− {-# INLINE writer #-}
41−
42− tell = Lift.lift . tell @tag
43− {-# INLINE tell #-}
44−
45− listen = Lift.liftListen (listen @tag)
46− {-# INLINE listen #-}
47−
48− pass = Lift.liftPass (pass @tag)
49− {-# INLINE pass #-}
src/Ether.hsnew file+25
@@ -0,0 +1,25 @@
1+module Ether
2+ ( module Control.Monad
3+ , module Control.Monad.Fix
4+ , module Control.Monad.Trans.Identity
5+ , module Data.Functor.Identity
6+ , module Data.Tagged
7+ , module Ether.Reader
8+ , module Ether.Writer
9+ , module Ether.State
10+ , module Ether.Except
11+ , module Ether.TagDispatch
12+ , module Ether.Handler
13+ ) where
14+
15+import Control.Monad
16+import Control.Monad.Fix
17+import Control.Monad.Trans.Identity
18+import Data.Functor.Identity
19+import Data.Tagged
20+import Ether.Reader
21+import Ether.Writer
22+import Ether.State
23+import Ether.Except
24+import Ether.TagDispatch
25+import Ether.Handler
src/Control/Monad/Ether/Except.hs → src/Ether/Except.hsrenamed+82−30
@@ -1,38 +1,61 @@
1−-- | See "Control.Monad.Except".
2−
3−module Control.Monad.Ether.Except
4− (
5− -- * MonadExcept class
6− MonadExcept
7− , throw
8− , catch
9− -- * The Except monad
10− , Except
11− , runExcept
12− -- * The ExceptT monad transformer
13− , ExceptT
14− , exceptT
15− , runExceptT
16− -- * Handle functions
17− , handleT
18− , handle
19− ) where
20−
21−import Control.Monad.Ether.Handle
22−import Control.Monad.Ether.Except.Class
23−import Control.Monad.Trans.Ether.Handler
1+module Ether.Except
2+ (
3+ -- * MonadExcept class
4+ MonadExcept
5+ , throw
6+ , catch
7+ -- * The Except monad
8+ , Except
9+ , runExcept
10+ -- * The ExceptT monad transformer
11+ , ExceptT
12+ , exceptT
13+ , runExceptT
14+ -- * MonadExcept class (implicit)
15+ , MonadExcept'
16+ , throw'
17+ , catch'
18+ -- * The Except monad (implicit)
19+ , Except'
20+ , runExcept'
21+ -- * The ExceptT monad transformer (implicit)
22+ , ExceptT'
23+ , exceptT'
24+ , runExceptT'
25+ -- * Internal labels
26+ , TAGGED
27+ , EXCEPT
28+ ) where
29+
2430import qualified Control.Monad.Except as T
2531import Control.Monad.Signatures (Catch)
26−import Data.Functor.Identity
32+import qualified Control.Monad.Trans.Lift.Catch as Lift
2733import Data.Coerce
34+import Data.Functor.Identity
35+
36+import Ether.Handler
37+import Ether.Internal
38+
39+class Monad m => MonadExcept tag e m | m tag -> e where
2840
29−-- | Runs an 'Except' and handles the exception with the given function.
30−handle :: forall tag e a . (e -> a) -> Except tag e a -> a
31−handle h m = runIdentity (handleT @tag h m)
41+ -- | Is used within a monadic computation to begin exception processing.
42+ throw :: e -> m a
43+
44+ -- | A handler function to handle previous exceptions and return to
45+ -- normal execution.
46+ catch :: m a -> (e -> m a) -> m a
47+
48+instance {-# OVERLAPPABLE #-}
49+ ( Lift.LiftCatch t
50+ , Monad (t m)
51+ , MonadExcept tag e m
52+ ) => MonadExcept tag e (t m) where
53+
54+ throw = Lift.lift . throw @tag
55+ {-# INLINE throw #-}
3256
33−-- | Runs an 'ExceptT' and handles the exception with the given function.
34−handleT :: forall tag e m a . Functor m => (e -> a) -> ExceptT tag e m a -> m a
35−handleT h m = fmap (either h id) (runExceptT @tag m)
57+ catch = Lift.liftCatch (catch @tag)
58+ {-# INLINE catch #-}
3659
3760-- | Encode type-level information for 'ExceptT'.
3861data EXCEPT
@@ -54,14 +77,17 @@ type ExceptT tag e = Handler (TAGGED EXCEPT tag) (T.ExceptT e)
5477-- | Runs an 'Except' and returns either an exception or a normal value.
5578runExcept :: forall tag e a . Except tag e a -> Either e a
5679runExcept = coerce (T.runExcept @e @a)
80+{-# INLINE runExcept #-}
5781
5882-- | Runs an 'ExceptT' and returns either an exception or a normal value.
5983runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
6084runExceptT = coerce (T.runExceptT @e @m @a)
85+{-# INLINE runExceptT #-}
6186
6287-- | Constructor for computations in the exception monad transformer.
6388exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
6489exceptT = coerce (T.ExceptT @e @m @a)
90+{-# INLINE exceptT #-}
6591
6692type instance HandleSuper EXCEPT e trans = ()
6793type instance HandleConstraint EXCEPT e trans m =
@@ -87,3 +113,29 @@ instance
87113 coerce (T.catchError @e @(trans m) @a) ::
88114 forall eff a . Catch e (Handler eff trans m) a
89115 {-# INLINE catch #-}
116+
117+type MonadExcept' e = MonadExcept e e
118+
119+throw' :: forall e m a . MonadExcept' e m => e -> m a
120+throw' = throw @e
121+{-# INLINE throw' #-}
122+
123+catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
124+catch' = catch @e
125+{-# INLINE catch' #-}
126+
127+type Except' e = Except e e
128+
129+runExcept' :: Except' e a -> Either e a
130+runExcept' = runExcept
131+{-# INLINE runExcept' #-}
132+
133+type ExceptT' e = ExceptT e e
134+
135+exceptT' :: m (Either e a) -> ExceptT' e m a
136+exceptT' = exceptT
137+{-# INLINE exceptT' #-}
138+
139+runExceptT' :: ExceptT' e m a -> m (Either e a)
140+runExceptT' = runExceptT
141+{-# INLINE runExceptT' #-}
src/Control/Monad/Trans/Ether/Handler.hs → src/Ether/Handler.hsrenamed+31−31
@@ -1,4 +1,4 @@
1−module Control.Monad.Trans.Ether.Handler
1+module Ether.Handler
22 ( Handler(..)
33 ) where
44
@@ -20,11 +20,11 @@ import qualified Control.Monad.Trans.Lift.Listen as Lift
2020import qualified Control.Monad.Trans.Lift.Pass as Lift
2121import qualified Control.Monad.Trans.Lift.CallCC as Lift
2222
23−import qualified Control.Monad.Cont.Class as Class
24−import qualified Control.Monad.Reader.Class as Class
25−import qualified Control.Monad.State.Class as Class
26−import qualified Control.Monad.Writer.Class as Class
27−import qualified Control.Monad.Error.Class as Class
23+import qualified Control.Monad.Cont.Class as Mtl
24+import qualified Control.Monad.Reader.Class as Mtl
25+import qualified Control.Monad.State.Class as Mtl
26+import qualified Control.Monad.Writer.Class as Mtl
27+import qualified Control.Monad.Error.Class as Mtl
2828
2929import GHC.Generics (Generic)
3030import Data.Coerce (coerce)
@@ -66,7 +66,7 @@ type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
6666newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
6767
6868coerceLiftBaseWith ::
69− LiftBaseWith b (trans m) a ->
69+ LiftBaseWith b (trans m) a ->
7070 LiftBaseWith b (Handler eff trans m) a
7171coerceLiftBaseWith lbw =
7272 unLBW (coerce (LBW lbw))
@@ -125,53 +125,53 @@ instance Lift.LiftCallCC trans => Lift.LiftCallCC (Handler eff trans) where
125125 (coerce :: Unpack eff trans m a)
126126
127127
128−-- Instances for mtl classes
128+-- Instances for mtl Mtles
129129
130130instance {-# OVERLAPPABLE #-}
131− ( Class.MonadCont m
131+ ( Mtl.MonadCont m
132132 , Lift.LiftCallCC trans
133133 , Monad (trans m)
134− ) => Class.MonadCont (Handler eff trans m)
134+ ) => Mtl.MonadCont (Handler eff trans m)
135135 where
136− callCC = Lift.liftCallCC' Class.callCC
136+ callCC = Lift.liftCallCC' Mtl.callCC
137137
138138instance {-# OVERLAPPABLE #-}
139− ( Class.MonadReader r m
139+ ( Mtl.MonadReader r m
140140 , Lift.LiftLocal trans
141141 , Monad (trans m)
142− ) => Class.MonadReader r (Handler eff trans m)
142+ ) => Mtl.MonadReader r (Handler eff trans m)
143143 where
144− ask = lift Class.ask
145− local = Lift.liftLocal Class.ask Class.local
146− reader = lift . Class.reader
144+ ask = lift Mtl.ask
145+ local = Lift.liftLocal Mtl.ask Mtl.local
146+ reader = lift . Mtl.reader
147147
148148instance {-# OVERLAPPABLE #-}
149− ( Class.MonadState s m
149+ ( Mtl.MonadState s m
150150 , MonadTrans trans
151151 , Monad (trans m)
152− ) => Class.MonadState s (Handler eff trans m)
152+ ) => Mtl.MonadState s (Handler eff trans m)
153153 where
154− get = lift Class.get
155− put = lift . Class.put
156− state = lift . Class.state
154+ get = lift Mtl.get
155+ put = lift . Mtl.put
156+ state = lift . Mtl.state
157157
158158instance {-# OVERLAPPABLE #-}
159− ( Class.MonadWriter w m
159+ ( Mtl.MonadWriter w m
160160 , Lift.LiftListen trans
161161 , Lift.LiftPass trans
162162 , Monad (trans m)
163− ) => Class.MonadWriter w (Handler eff trans m)
163+ ) => Mtl.MonadWriter w (Handler eff trans m)
164164 where
165− writer = lift . Class.writer
166− tell = lift . Class.tell
167− listen = Lift.liftListen Class.listen
168− pass = Lift.liftPass Class.pass
165+ writer = lift . Mtl.writer
166+ tell = lift . Mtl.tell
167+ listen = Lift.liftListen Mtl.listen
168+ pass = Lift.liftPass Mtl.pass
169169
170170instance {-# OVERLAPPABLE #-}
171− ( Class.MonadError e m
171+ ( Mtl.MonadError e m
172172 , Lift.LiftCatch trans
173173 , Monad (trans m)
174− ) => Class.MonadError e (Handler eff trans m)
174+ ) => Mtl.MonadError e (Handler eff trans m)
175175 where
176− throwError = lift . Class.throwError
177− catchError = Lift.liftCatch Class.catchError
176+ throwError = lift . Mtl.throwError
177+ catchError = Lift.liftCatch Mtl.catchError
src/Ether/Internal.hsnew file+173
@@ -0,0 +1,173 @@
1+module Ether.Internal
2+ ( Tagged(..)
3+ , TagsK
4+ , Tags
5+ , HasLens(..)
6+ , LensLike
7+ , Lens
8+ , Lens'
9+ , view
10+ , over
11+ , HList(..)
12+ , KindOf
13+ , TAGGED
14+ , HandleSuper
15+ , HandleConstraint
16+ , Handle(..)
17+ ) where
18+
19+import Control.Applicative
20+import Control.Monad
21+import Data.Coerce
22+import Data.Functor.Identity
23+import Data.Kind
24+import Data.List as List
25+import Data.Tagged
26+import Data.Traversable
27+import GHC.Exts (Constraint)
28+import qualified Language.Haskell.TH as TH
29+
30+data TAGGED e t
31+
32+type K_Monad = Type -> Type
33+
34+type K_Trans = K_Monad -> K_Monad
35+
36+type family
37+ HandleSuper
38+ (eff :: keff)
39+ (p :: kp)
40+ (trans :: K_Trans)
41+ :: Constraint
42+
43+type family
44+ HandleConstraint
45+ (eff :: keff)
46+ (p :: kp)
47+ (trans :: K_Trans) (m :: K_Monad)
48+ :: Constraint
49+
50+class
51+ HandleSuper eff p trans =>
52+ Handle eff p (trans :: K_Trans) | eff trans -> p
53+ where
54+ handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
55+
56+type LensLike f s t a b = (a -> f b) -> s -> f t
57+
58+type Lens s t a b = forall f. Functor f => LensLike f s t a b
59+
60+type Lens' s a = Lens s s a a
61+
62+class HasLens tag outer inner | tag outer -> inner where
63+ lensOf :: Lens' outer inner
64+
65+instance HasLens a a a where
66+ lensOf = id
67+ {-# INLINE lensOf #-}
68+
69+view :: LensLike (Const a) s t a b -> s -> a
70+view l = coerce (l Const)
71+{-# INLINE view #-}
72+
73+over :: LensLike Identity s t a b -> (a -> b) -> s -> t
74+over = coerce
75+{-# INLINE over #-}
76+
77+data HList xs where
78+ HNil :: HList '[]
79+ HCons :: x -> HList xs -> HList (x ': xs)
80+
81+type KindOf (a :: k) = k
82+
83+type family TagsK (p :: Type) :: [Type]
84+type family Tags (p :: Type) :: HList (TagsK p)
85+
86+return []
87+
88+type instance TagsK () = '[]
89+type instance TagsK (Tagged t a) = '[KindOf t]
90+type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
91+
92+return []
93+
94+type instance Tags () = 'HNil
95+type instance Tags (Tagged t a) = 'HCons t 'HNil
96+type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
97+
98+do
99+ let
100+ tupCount = 62
101+ names = [1..] >>= flip replicateM ['a'..'z']
102+ varNames <- traverse TH.newName (take tupCount names)
103+ fmap List.concat $
104+ for (List.drop 2 (List.inits varNames)) $
105+ \varNames' -> do
106+ let n = List.length varNames'
107+ tagsInstances <- for [() | n > 2] $ \() -> do
108+ tag <- TH.newName "tag"
109+ let
110+ (cur:rest) = varNames'
111+ tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
112+ ( TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur :
113+ map TH.VarT rest )
114+ tupTy' = foldl TH.AppT (TH.ConT (TH.tupleTypeName (n-1)))
115+ (map TH.VarT rest)
116+ return $
117+ TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy]
118+ ( TH.PromotedConsT `TH.AppT` (TH.ConT ''KindOf `TH.AppT` TH.VarT tag) `TH.AppT`
119+ (TH.ConT ''TagsK `TH.AppT` tupTy') ))
120+ return tagsInstances
121+do
122+ let
123+ tupCount = 62
124+ names = [1..] >>= flip replicateM ['a'..'z']
125+ varNames <- traverse TH.newName (take tupCount names)
126+ fmap List.concat $
127+ for (List.drop 2 (List.inits varNames)) $
128+ \varNames' -> do
129+ let n = List.length varNames'
130+ tagsInstances <- for [() | n > 2] $ \() -> do
131+ tag <- TH.newName "tag"
132+ let
133+ (cur:rest) = varNames'
134+ tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
135+ ( TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur :
136+ map TH.VarT rest )
137+ tupTy' = foldl TH.AppT (TH.ConT (TH.tupleTypeName (n-1)))
138+ (map TH.VarT rest)
139+ tagsInst =
140+ TH.TySynInstD ''Tags (TH.TySynEqn [tupTy]
141+ ( TH.PromotedT 'HCons `TH.AppT` TH.VarT tag `TH.AppT`
142+ (TH.ConT ''Tags `TH.AppT` tupTy') ))
143+ return tagsInst
144+ hasLensInstances <- for [0..n-1] $ \k -> do
145+ tag <- TH.newName "tag"
146+ let
147+ (prev, cur:next) = List.splitAt k varNames'
148+ tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
149+ ( map TH.VarT prev ++
150+ [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
151+ map TH.VarT next )
152+ cur' <- TH.newName "x"
153+ f <- TH.newName "f"
154+ return $
155+ TH.InstanceD Nothing []
156+ (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
157+ [ TH.FunD 'lensOf
158+ [ TH.Clause
159+ [TH.VarP f, TH.TupP
160+ ( map TH.VarP prev ++
161+ [TH.ConP 'Tagged [TH.VarP cur]] ++
162+ map TH.VarP next )]
163+ (TH.NormalB $
164+ TH.VarE 'fmap `TH.AppE`
165+ (TH.LamE [TH.VarP cur']
166+ (TH.TupE
167+ ( map TH.VarE prev ++
168+ [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
169+ map TH.VarE next ))) `TH.AppE`
170+ (TH.VarE f `TH.AppE` TH.VarE cur) )
171+ [] ],
172+ TH.PragmaD (TH.InlineP 'lensOf TH.Inline TH.FunLike TH.AllPhases) ]
173+ return $ tagsInstances ++ hasLensInstances
src/Ether/Reader.hsnew file+264
@@ -0,0 +1,264 @@
1+module Ether.Reader
2+ (
3+ -- * MonadReader class
4+ MonadReader
5+ , ask
6+ , local
7+ , reader
8+ , asks
9+ -- * The Reader monad
10+ , Reader
11+ , runReader
12+ -- * The ReaderT monad transformer
13+ , ReaderT
14+ , readerT
15+ , runReaderT
16+ -- * The Reader monad (flattened)
17+ , Readers
18+ , runReaders
19+ -- * The ReaderT monad transformer (flattened)
20+ , ReadersT
21+ , runReadersT
22+ -- * MonadReader class (implicit)
23+ , MonadReader'
24+ , local'
25+ , ask'
26+ , reader'
27+ , asks'
28+ -- * The Reader monad (implicit)
29+ , Reader'
30+ , runReader'
31+ -- * The ReaderT monad transformer (implicit)
32+ , ReaderT'
33+ , readerT'
34+ , runReaderT'
35+ -- * Internal labels
36+ , TAGGED
37+ , READER
38+ , READERS
39+ ) where
40+
41+import qualified Control.Monad.Reader as T
42+import qualified Control.Monad.Trans.Lift.Local as Lift
43+import Control.Monad.Trans.Lift.Local (Local)
44+import Data.Coerce
45+import Data.Functor.Identity
46+import Data.Kind
47+
48+import Ether.Handler
49+import Ether.Internal
50+
51+class Monad m => MonadReader tag r m | m tag -> r where
52+
53+ {-# MINIMAL (ask | reader), local #-}
54+
55+ -- | Retrieves the monad environment.
56+ ask :: m r
57+ ask = reader @tag id
58+
59+ -- | Executes a computation in a modified environment.
60+ local
61+ :: (r -> r)
62+ -- ^ The function to modify the environment.
63+ -> m a
64+ -- ^ @Reader@ to run in the modified environment.
65+ -> m a
66+
67+ -- | Retrieves a function of the current environment.
68+ reader
69+ :: (r -> a)
70+ -- ^ The selector function to apply to the environment.
71+ -> m a
72+ reader f = fmap f (ask @tag)
73+
74+instance {-# OVERLAPPABLE #-}
75+ ( Lift.LiftLocal t
76+ , Monad (t m)
77+ , MonadReader tag r m
78+ ) => MonadReader tag r (t m)
79+ where
80+
81+ ask = Lift.lift (ask @tag)
82+ {-# INLINE ask #-}
83+
84+ local = Lift.liftLocal (ask @tag) (local @tag)
85+ {-# INLINE local #-}
86+
87+ reader = Lift.lift . reader @tag
88+ {-# INLINE reader #-}
89+
90+instance {-# OVERLAPPABLE #-}
91+ ( Monad (trans m)
92+ , MonadReader tag r (Handler effs trans m)
93+ ) => MonadReader tag r (Handler (eff ': effs) trans (m :: Type -> Type))
94+ where
95+
96+ ask =
97+ (coerce ::
98+ Handler effs trans m r ->
99+ Handler (eff ': effs) trans m r)
100+ (ask @tag)
101+ {-# INLINE ask #-}
102+
103+ local =
104+ (coerce :: forall a .
105+ Lift.Local r (Handler effs trans m) a ->
106+ Lift.Local r (Handler (eff ': effs) trans m) a)
107+ (local @tag)
108+ {-# INLINE local #-}
109+
110+ reader =
111+ (coerce :: forall a .
112+ ((r -> a) -> Handler effs trans m a) ->
113+ ((r -> a) -> Handler (eff ': effs) trans m a))
114+ (reader @tag)
115+ {-# INLINE reader #-}
116+
117+-- | Retrieves a function of the current environment.
118+asks
119+ :: forall tag r m a
120+ . MonadReader tag r m
121+ => (r -> a)
122+ -- ^ The selector function to apply to the environment.
123+ -> m a
124+asks = reader @tag
125+{-# INLINE asks #-}
126+
127+-- | Encode type-level information for 'ReaderT'.
128+data READER
129+
130+-- | The parameterizable reader monad.
131+--
132+-- Computations are functions of a shared environment.
133+--
134+-- The 'return' function ignores the environment, while '>>=' passes
135+-- the inherited environment to both subcomputations.
136+type Reader tag r = ReaderT tag r Identity
137+
138+-- | The reader monad transformer,
139+-- which adds a read-only environment to the given monad.
140+--
141+-- The 'return' function ignores the environment, while '>>=' passes
142+-- the inherited environment to both subcomputations.
143+type ReaderT tag r = Handler (TAGGED READER tag) (T.ReaderT r)
144+
145+-- | Constructor for computations in the reader monad transformer.
146+readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
147+readerT = coerce (T.ReaderT @r @m @a)
148+{-# INLINE readerT #-}
149+
150+-- | Runs a 'ReaderT' with the given environment
151+-- and returns the final value.
152+runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
153+runReaderT = coerce (T.runReaderT @r @_ @m @a)
154+{-# INLINE runReaderT #-}
155+
156+-- | Runs a 'ReaderT' with the given environment
157+-- and returns the final value.
158+runReader :: forall tag r a . Reader tag r a -> r -> a
159+runReader = coerce (T.runReader @r @a)
160+{-# INLINE runReader #-}
161+
162+type instance HandleSuper READER r trans = ()
163+type instance HandleConstraint READER r trans m =
164+ T.MonadReader r (trans m)
165+
166+instance Handle READER r (T.ReaderT r) where
167+ handling r = r
168+ {-# INLINE handling #-}
169+
170+instance
171+ ( Handle READER r trans
172+ , Monad m, Monad (trans m)
173+ ) => MonadReader tag r (Handler (TAGGED READER tag) trans m)
174+ where
175+
176+ ask =
177+ handling @READER @r @trans @m $
178+ coerce (T.ask @r @(trans m))
179+ {-# INLINE ask #-}
180+
181+ local =
182+ handling @READER @r @trans @m $
183+ coerce (T.local @r @(trans m) @a) ::
184+ forall eff a . Local r (Handler eff trans m) a
185+ {-# INLINE local #-}
186+
187+ reader =
188+ handling @READER @r @trans @m $
189+ coerce (T.reader @r @(trans m) @a) ::
190+ forall eff a . (r -> a) -> Handler eff trans m a
191+ {-# INLINE reader #-}
192+
193+instance
194+ ( HasLens tag payload r
195+ , Handle READER payload trans
196+ , Monad m, Monad (trans m)
197+ ) => MonadReader tag r (Handler (TAGGED READER tag ': effs) trans m)
198+ where
199+
200+ ask =
201+ handling @READER @payload @trans @m $
202+ (coerce :: forall eff a .
203+ trans m a ->
204+ Handler eff trans m a)
205+ (T.asks (view (lensOf @tag @payload @r)))
206+ {-# INLINE ask #-}
207+
208+ local f =
209+ handling @READER @payload @trans @m $
210+ (coerce :: forall eff a .
211+ (trans m a -> trans m a) ->
212+ (Handler eff trans m a -> Handler eff trans m a))
213+ (T.local (over (lensOf @tag @payload @r) f))
214+ {-# INLINE local #-}
215+
216+type family READERS (ts :: HList xs) :: [Type] where
217+ READERS 'HNil = '[]
218+ READERS ('HCons t ts) = TAGGED READER t ': READERS ts
219+
220+type ReadersT r = Handler (READERS (Tags r)) (T.ReaderT r)
221+
222+type Readers r = ReadersT r Identity
223+
224+runReadersT :: forall p m a . ReadersT p m a -> p -> m a
225+runReadersT = coerce (T.runReaderT @p @_ @m @a)
226+{-# INLINE runReadersT #-}
227+
228+runReaders :: forall p a . Readers p a -> p -> a
229+runReaders = coerce (T.runReader @p @a)
230+{-# INLINE runReaders #-}
231+
232+type ReaderT' r = ReaderT r r
233+
234+readerT' :: (r -> m a) -> ReaderT' r m a
235+readerT' = readerT
236+{-# INLINE readerT' #-}
237+
238+runReaderT' :: ReaderT' r m a -> r -> m a
239+runReaderT' = runReaderT
240+{-# INLINE runReaderT' #-}
241+
242+type Reader' r = Reader r r
243+
244+runReader' :: Reader' r a -> r -> a
245+runReader' = runReader
246+{-# INLINE runReader' #-}
247+
248+type MonadReader' r = MonadReader r r
249+
250+local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
251+local' = local @r
252+{-# INLINE local' #-}
253+
254+ask' :: forall r m . MonadReader' r m => m r
255+ask' = ask @r
256+{-# INLINE ask' #-}
257+
258+reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
259+reader' = reader @r
260+{-# INLINE reader' #-}
261+
262+asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
263+asks' = asks @r
264+{-# INLINE asks' #-}
src/Ether/State.hsnew file+475
@@ -0,0 +1,475 @@
1+module Ether.State
2+ (
3+ -- * MonadState class
4+ MonadState
5+ , get
6+ , put
7+ , state
8+ , modify
9+ , gets
10+ -- * The State monad
11+ , State
12+ , runState
13+ , evalState
14+ , execState
15+ -- * The StateT monad transformer
16+ , StateT
17+ , stateT
18+ , runStateT
19+ , evalStateT
20+ , execStateT
21+ -- * The State monad (lazy)
22+ , LazyState
23+ , runLazyState
24+ , evalLazyState
25+ , execLazyState
26+ -- * The StateT monad transformer (lazy)
27+ , LazyStateT
28+ , lazyStateT
29+ , runLazyStateT
30+ , evalLazyStateT
31+ , execLazyStateT
32+ -- * The State monad (flattened)
33+ , States
34+ , runStates
35+ -- * The StateT monad transformer (flattened)
36+ , StatesT
37+ , runStatesT
38+ -- * MonadState class (implicit)
39+ , MonadState'
40+ , get'
41+ , put'
42+ , state'
43+ , modify'
44+ , gets'
45+ -- * The State monad (implicit)
46+ , State'
47+ , runState'
48+ , evalState'
49+ , execState'
50+ -- * The StateT monad transformer (implicit)
51+ , StateT'
52+ , stateT'
53+ , runStateT'
54+ , evalStateT'
55+ , execStateT'
56+ -- * The State monad (lazy, implicit)
57+ , LazyState'
58+ , runLazyState'
59+ , evalLazyState'
60+ , execLazyState'
61+ -- * The StateT monad transformer (lazy, implicit)
62+ , LazyStateT'
63+ , lazyStateT'
64+ , runLazyStateT'
65+ , evalLazyStateT'
66+ , execLazyStateT'
67+ -- * Zoom
68+ , ZoomT
69+ , zoom
70+ -- * Internal labels
71+ , TAGGED
72+ , STATE
73+ , STATES
74+ , ZOOM
75+ ) where
76+
77+import qualified Control.Monad.State.Class as T
78+import qualified Control.Monad.Trans as Lift
79+import Control.Monad.Trans.Identity
80+import qualified Control.Monad.Trans.State.Lazy as T.Lazy
81+import qualified Control.Monad.Trans.State.Strict as T.Strict
82+import Data.Coerce
83+import Data.Functor.Identity
84+import Data.Kind
85+import Data.Proxy
86+import Data.Reflection
87+
88+import Ether.Handler
89+import Ether.Internal
90+
91+class Monad m => MonadState tag s m | m tag -> s where
92+
93+ {-# MINIMAL state | get, put #-}
94+
95+ -- | Return the state from the internals of the monad.
96+ get :: m s
97+ get = state @tag (\s -> (s, s))
98+
99+ -- | Replace the state inside the monad.
100+ put :: s -> m ()
101+ put s = state @tag (\_ -> ((), s))
102+
103+ -- | Embed a simple state action into the monad.
104+ state :: (s -> (a, s)) -> m a
105+ state f = do
106+ s <- get @tag
107+ let ~(a, s') = f s
108+ put @tag s'
109+ return a
110+
111+instance {-# OVERLAPPABLE #-}
112+ ( Lift.MonadTrans t
113+ , Monad (t m)
114+ , MonadState tag s m
115+ ) => MonadState tag s (t m)
116+ where
117+
118+ get = Lift.lift (get @tag)
119+ {-# INLINE get #-}
120+
121+ put = Lift.lift . put @tag
122+ {-# INLINE put #-}
123+
124+ state = Lift.lift . state @tag
125+ {-# INLINE state #-}
126+
127+instance {-# OVERLAPPABLE #-}
128+ ( Monad (trans m)
129+ , MonadState tag s (Handler effs trans m)
130+ ) => MonadState tag s (Handler (eff ': effs) trans (m :: Type -> Type))
131+ where
132+
133+ get =
134+ (coerce ::
135+ Handler effs trans m s ->
136+ Handler (eff ': effs) trans m s)
137+ (get @tag)
138+ {-# INLINE get #-}
139+
140+ put =
141+ (coerce ::
142+ (s -> Handler effs trans m ()) ->
143+ (s -> Handler (eff ': effs) trans m ()))
144+ (put @tag)
145+ {-# INLINE put #-}
146+
147+ state =
148+ (coerce :: forall a .
149+ ((s -> (a, s)) -> Handler effs trans m a) ->
150+ ((s -> (a, s)) -> Handler (eff ': effs) trans m a))
151+ (state @tag)
152+ {-# INLINE state #-}
153+
154+-- | Encode type-level information for 'StateT'.
155+data STATE
156+
157+-- | Modifies the state inside a state monad.
158+modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
159+modify f = state @tag (\s -> ((), f s))
160+{-# INLINABLE modify #-}
161+
162+-- | Gets specific component of the state, using a projection function supplied.
163+gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
164+gets f = fmap f (get @tag)
165+{-# INLINABLE gets #-}
166+
167+type instance HandleSuper STATE s trans = ()
168+type instance HandleConstraint STATE s trans m =
169+ T.MonadState s (trans m)
170+
171+instance Handle STATE s (T.Strict.StateT s) where
172+ handling r = r
173+ {-# INLINE handling #-}
174+
175+instance Handle STATE s (T.Lazy.StateT s) where
176+ handling r = r
177+ {-# INLINE handling #-}
178+
179+instance
180+ ( Handle STATE s trans
181+ , Monad m, Monad (trans m)
182+ ) => MonadState tag s (Handler (TAGGED STATE tag) trans m)
183+ where
184+
185+ get =
186+ handling @STATE @s @trans @m $
187+ coerce (T.get @s @(trans m))
188+ {-# INLINE get #-}
189+
190+ put =
191+ handling @STATE @s @trans @m $
192+ coerce (T.put @s @(trans m))
193+ {-# INLINE put #-}
194+
195+ state =
196+ handling @STATE @s @trans @m $
197+ coerce (T.state @s @(trans m) @a) ::
198+ forall eff a . (s -> (a, s)) -> Handler eff trans m a
199+ {-# INLINE state #-}
200+
201+instance
202+ ( HasLens tag payload s
203+ , Handle STATE payload trans
204+ , Monad m, Monad (trans m)
205+ ) => MonadState tag s (Handler (TAGGED STATE tag ': effs) trans m)
206+ where
207+
208+ get =
209+ handling @STATE @payload @trans @m $
210+ (coerce :: forall eff a .
211+ trans m a ->
212+ Handler eff trans m a)
213+ (T.gets (view (lensOf @tag @payload @s)))
214+ {-# INLINE get #-}
215+
216+ put s =
217+ handling @STATE @payload @trans @m $
218+ (coerce :: forall eff a .
219+ trans m a ->
220+ Handler eff trans m a)
221+ (T.modify (over (lensOf @tag @payload @s) (const s)))
222+ {-# INLINE put #-}
223+
224+ state f =
225+ handling @STATE @payload @trans @m $
226+ (coerce :: forall eff a .
227+ trans m a ->
228+ Handler eff trans m a)
229+ (T.state (lensOf @tag @payload @s f))
230+ {-# INLINE state #-}
231+
232+-- | The parametrizable state monad.
233+--
234+-- Computations have access to a mutable state.
235+--
236+-- The 'return' function leaves the state unchanged, while '>>=' uses
237+-- the final state of the first computation as the initial state of the second.
238+type State tag r = StateT tag r Identity
239+
240+-- | The state monad transformer.
241+--
242+-- The 'return' function leaves the state unchanged, while '>>=' uses
243+-- the final state of the first computation as the initial state of the second.
244+type StateT tag s = Handler (TAGGED STATE tag) (T.Strict.StateT s)
245+
246+-- | Constructor for computations in the state monad transformer.
247+stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
248+stateT = coerce (T.Strict.StateT @s @m @a)
249+{-# INLINE stateT #-}
250+
251+-- | Runs a 'StateT' with the given initial state
252+-- and returns both the final value and the final state.
253+runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
254+runStateT = coerce (T.Strict.runStateT @s @m @a)
255+{-# INLINE runStateT #-}
256+
257+-- | Runs a 'StateT' with the given initial state
258+-- and returns the final value, discarding the final state.
259+evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
260+evalStateT = coerce (T.Strict.evalStateT @m @s @a)
261+{-# INLINE evalStateT #-}
262+
263+-- | Runs a 'StateT' with the given initial state
264+-- and returns the final state, discarding the final value.
265+execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
266+execStateT = coerce (T.Strict.execStateT @m @s @a)
267+{-# INLINE execStateT #-}
268+
269+-- | Runs a 'State' with the given initial state
270+-- and returns both the final value and the final state.
271+runState :: forall tag s a . State tag s a -> s -> (a, s)
272+runState = coerce (T.Strict.runState @s @a)
273+{-# INLINE runState #-}
274+
275+-- | Runs a 'State' with the given initial state
276+-- and returns the final value, discarding the final state.
277+evalState :: forall tag s a . State tag s a -> s -> a
278+evalState = coerce (T.Strict.evalState @s @a)
279+{-# INLINE evalState #-}
280+
281+-- | Runs a 'State' with the given initial state
282+-- and returns the final state, discarding the final value.
283+execState :: forall tag s a . State tag s a -> s -> s
284+execState = coerce (T.Strict.execState @s @a)
285+{-# INLINE execState #-}
286+
287+-- | The parametrizable state monad.
288+--
289+-- Computations have access to a mutable state.
290+--
291+-- The 'return' function leaves the state unchanged, while '>>=' uses
292+-- the final state of the first computation as the initial state of the second.
293+type LazyState tag r = LazyStateT tag r Identity
294+
295+-- | The state monad transformer.
296+--
297+-- The 'return' function leaves the state unchanged, while '>>=' uses
298+-- the final state of the first computation as the initial state of the second.
299+type LazyStateT tag s = Handler (TAGGED STATE tag) (T.Lazy.StateT s)
300+
301+-- | Constructor for computations in the state monad transformer.
302+lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
303+lazyStateT = coerce (T.Lazy.StateT @s @m @a)
304+{-# INLINE lazyStateT #-}
305+
306+-- | Runs a 'StateT' with the given initial state
307+-- and returns both the final value and the final state.
308+runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
309+runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
310+{-# INLINE runLazyStateT #-}
311+
312+-- | Runs a 'StateT' with the given initial state
313+-- and returns the final value, discarding the final state.
314+evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
315+evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
316+{-# INLINE evalLazyStateT #-}
317+
318+-- | Runs a 'StateT' with the given initial state
319+-- and returns the final state, discarding the final value.
320+execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
321+execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
322+{-# INLINE execLazyStateT #-}
323+
324+-- | Runs a 'State' with the given initial state
325+-- and returns both the final value and the final state.
326+runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
327+runLazyState = coerce (T.Lazy.runState @s @a)
328+{-# INLINE runLazyState #-}
329+
330+-- | Runs a 'State' with the given initial state
331+-- and returns the final value, discarding the final state.
332+evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
333+evalLazyState = coerce (T.Lazy.evalState @s @a)
334+{-# INLINE evalLazyState #-}
335+
336+-- | Runs a 'State' with the given initial state
337+-- and returns the final state, discarding the final value.
338+execLazyState :: forall tag s a . LazyState tag s a -> s -> s
339+execLazyState = coerce (T.Lazy.execState @s @a)
340+{-# INLINE execLazyState #-}
341+
342+type family STATES (ts :: HList xs) :: [Type] where
343+ STATES 'HNil = '[]
344+ STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
345+
346+type StatesT s = Handler (STATES (Tags s)) (T.Strict.StateT s)
347+
348+type States s = StatesT s Identity
349+
350+runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
351+runStatesT = coerce (T.Strict.runStateT @p @m @a)
352+{-# INLINE runStatesT #-}
353+
354+runStates :: forall p a . States p a -> p -> (a, p)
355+runStates = coerce (T.Strict.runState @p @a)
356+{-# INLINE runStates #-}
357+
358+type StateT' s = StateT s s
359+
360+stateT' :: (s -> m (a, s)) -> StateT' s m a
361+stateT' = stateT
362+{-# INLINE stateT' #-}
363+
364+runStateT' :: StateT' s m a -> s -> m (a, s)
365+runStateT' = runStateT
366+{-# INLINE runStateT' #-}
367+
368+runState' :: State' s a -> s -> (a, s)
369+runState' = runState
370+{-# INLINE runState' #-}
371+
372+evalStateT' :: Monad m => StateT' s m a -> s -> m a
373+evalStateT' = evalStateT
374+{-# INLINE evalStateT' #-}
375+
376+type State' s = State s s
377+
378+evalState' :: State' s a -> s -> a
379+evalState' = evalState
380+{-# INLINE evalState' #-}
381+
382+execStateT' :: Monad m => StateT' s m a -> s -> m s
383+execStateT' = execStateT
384+{-# INLINE execStateT' #-}
385+
386+execState' :: State' s a -> s -> s
387+execState' = execState
388+{-# INLINE execState' #-}
389+
390+type LazyStateT' s = LazyStateT s s
391+
392+lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
393+lazyStateT' = lazyStateT
394+{-# INLINE lazyStateT' #-}
395+
396+runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
397+runLazyStateT' = runLazyStateT
398+{-# INLINE runLazyStateT' #-}
399+
400+runLazyState' :: LazyState' s a -> s -> (a, s)
401+runLazyState' = runLazyState
402+{-# INLINE runLazyState' #-}
403+
404+evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
405+evalLazyStateT' = evalLazyStateT
406+{-# INLINE evalLazyStateT' #-}
407+
408+type LazyState' s = LazyState s s
409+
410+evalLazyState' :: LazyState' s a -> s -> a
411+evalLazyState' = evalLazyState
412+{-# INLINE evalLazyState' #-}
413+
414+execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
415+execLazyStateT' = execLazyStateT
416+{-# INLINE execLazyStateT' #-}
417+
418+execLazyState' :: LazyState' s a -> s -> s
419+execLazyState' = execLazyState
420+{-# INLINE execLazyState' #-}
421+
422+type MonadState' s = MonadState s s
423+
424+get' :: forall s m . MonadState' s m => m s
425+get' = get @s
426+{-# INLINE get' #-}
427+
428+gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
429+gets' = gets @s
430+{-# INLINE gets' #-}
431+
432+put' :: forall s m . MonadState' s m => s -> m ()
433+put' = put @s
434+{-# INLINE put' #-}
435+
436+state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
437+state' = state @s
438+{-# INLINE state' #-}
439+
440+modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
441+modify' = modify @s
442+{-# INLINE modify' #-}
443+
444+-- | Encode type-level information for 'zoom'.
445+data ZOOM t z
446+
447+type ZoomT t (z :: Type) = Handler (ZOOM t z) IdentityT
448+
449+newtype ReifiedLens s t a b = Lens (Lens s t a b)
450+
451+type ReifiedLens' s a = ReifiedLens s s a a
452+
453+-- | Zoom into a part of a state using a lens.
454+zoom
455+ :: forall tag sOuter sInner m a
456+ . Lens' sOuter sInner
457+ -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
458+ -> m a
459+zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
460+{-# INLINE zoom #-}
461+
462+instance
463+ ( MonadState tag sOuter m
464+ , Reifies z (ReifiedLens' sOuter sInner)
465+ , trans ~ IdentityT
466+ ) => MonadState tag sInner (Handler (ZOOM tag z) trans m)
467+ where
468+ state =
469+ (coerce :: forall eff r a .
470+ (r -> m a) ->
471+ (r -> Handler eff trans m a))
472+ (state @tag . l)
473+ where
474+ Lens l = reflect (Proxy :: Proxy z)
475+ {-# INLINE state #-}
src/Ether/TagDispatch.hsnew file+188
@@ -0,0 +1,188 @@
1+{- |
2+
3+Type-level machinery to manipulate constraints on the monad
4+transformer stack.
5+
6+Out of the box it provides the following dispatch strategies:
7+
8+* 'tagAttach' to use functions defined using untagged monad classes
9+ as if they were defined using tagged ones.
10+
11+* 'tagReplace' to use functions defined using one tag
12+ as if they were defined using another one.
13+
14+> import Ether
15+> import Control.Monad.State as Mtl
16+>
17+> data Foo
18+> data Bar
19+>
20+> f :: Mtl.MonadState Int m => m String
21+> f = fmap show Mtl.get
22+>
23+> g :: Ether.MonadState Foo Int m => m String
24+> g = tagAttach @Foo f
25+>
26+> h :: Ether.MonadState Bar Int m => m String
27+> h = tagReplace @Foo @Bar g
28+
29+-}
30+
31+module Ether.TagDispatch
32+ (
33+ -- * The Tag Attach monad transformer
34+ TagAttachT
35+ , tagAttach
36+ -- * The Tag Replace monad transformer
37+ , TagReplaceT
38+ , tagReplace
39+ -- * Internal labels
40+ , TAG_ATTACH
41+ , TAG_REPLACE
42+ ) where
43+
44+import qualified Control.Monad.Error.Class as Mtl
45+import qualified Control.Monad.Reader.Class as Mtl
46+import qualified Control.Monad.State.Class as Mtl
47+import qualified Control.Monad.Writer.Class as Mtl
48+
49+import Ether.Except
50+import Ether.Reader
51+import Ether.State
52+import Ether.Writer
53+import Ether.Handler
54+
55+import Control.Monad.Trans.Identity
56+import Data.Coerce
57+
58+-- | Encode type-level information for 'tagAttach'.
59+data TAG_ATTACH t
60+
61+type TagAttachT t = Handler (TAG_ATTACH t) IdentityT
62+
63+-- | Attach a tag to untagged transformers.
64+tagAttach :: forall tag m a . TagAttachT tag m a -> m a
65+tagAttach = coerce (runIdentityT @_ @m @a)
66+{-# INLINE tagAttach #-}
67+
68+instance
69+ ( MonadReader tag r m, trans ~ IdentityT
70+ ) => Mtl.MonadReader r (Handler (TAG_ATTACH tag) trans m)
71+ where
72+
73+ ask = ask @tag
74+ {-# INLINE ask #-}
75+
76+ local = local @tag
77+ {-# INLINE local #-}
78+
79+ reader = reader @tag
80+ {-# INLINE reader #-}
81+
82+instance
83+ ( MonadState tag s m, trans ~ IdentityT
84+ ) => Mtl.MonadState s (Handler (TAG_ATTACH tag) trans m)
85+ where
86+
87+ get = get @tag
88+ {-# INLINE get #-}
89+
90+ put = put @tag
91+ {-# INLINE put #-}
92+
93+ state = state @tag
94+ {-# INLINE state #-}
95+
96+instance
97+ ( MonadExcept tag e m, trans ~ IdentityT
98+ ) => Mtl.MonadError e (Handler (TAG_ATTACH tag) trans m)
99+ where
100+
101+ throwError = throw @tag
102+ {-# INLINE throwError #-}
103+
104+ catchError = catch @tag
105+ {-# INLINE catchError #-}
106+
107+instance
108+ ( MonadWriter tag w m, trans ~ IdentityT
109+ ) => Mtl.MonadWriter w (Handler (TAG_ATTACH tag) trans m)
110+ where
111+
112+ writer = writer @tag
113+ {-# INLINE writer #-}
114+
115+ tell = tell @tag
116+ {-# INLINE tell #-}
117+
118+ listen = listen @tag
119+ {-# INLINE listen #-}
120+
121+ pass = pass @tag
122+ {-# INLINE pass #-}
123+
124+-- | Encode type-level information for 'tagReplace'.
125+data TAG_REPLACE tOld tNew
126+
127+type TagReplaceT tOld tNew = Handler (TAG_REPLACE tOld tNew) IdentityT
128+
129+-- | Replace a tag with another tag.
130+tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
131+tagReplace = coerce (runIdentityT @_ @m @a)
132+{-# INLINE tagReplace #-}
133+
134+instance
135+ ( MonadReader tNew r m, trans ~ IdentityT
136+ ) => MonadReader tOld r (Handler (TAG_REPLACE tOld tNew) trans m)
137+ where
138+
139+ ask = ask @tNew
140+ {-# INLINE ask #-}
141+
142+ local = local @tNew
143+ {-# INLINE local #-}
144+
145+ reader = reader @tNew
146+ {-# INLINE reader #-}
147+
148+instance
149+ ( MonadState tNew s m, trans ~ IdentityT
150+ ) => MonadState tOld s (Handler (TAG_REPLACE tOld tNew) trans m)
151+ where
152+
153+ get = get @tNew
154+ {-# INLINE get #-}
155+
156+ put = put @tNew
157+ {-# INLINE put #-}
158+
159+ state = state @tNew
160+ {-# INLINE state #-}
161+
162+instance
163+ ( MonadExcept tNew e m, trans ~ IdentityT
164+ ) => MonadExcept tOld e (Handler (TAG_REPLACE tOld tNew) trans m)
165+ where
166+
167+ throw = throw @tNew
168+ {-# INLINE throw #-}
169+
170+ catch = catch @tNew
171+ {-# INLINE catch #-}
172+
173+instance
174+ ( MonadWriter tNew w m, trans ~ IdentityT
175+ ) => MonadWriter tOld w (Handler (TAG_REPLACE tOld tNew) trans m)
176+ where
177+
178+ writer = writer @tNew
179+ {-# INLINE writer #-}
180+
181+ tell = tell @tNew
182+ {-# INLINE tell #-}
183+
184+ listen = listen @tNew
185+ {-# INLINE listen #-}
186+
187+ pass = pass @tNew
188+ {-# INLINE pass #-}
src/Control/Monad/Ether/Writer.hs → src/Ether/Writer.hsrenamed+127−28
@@ -1,33 +1,93 @@
1−-- | See "Control.Monad.Writer".
2−
3−module Control.Monad.Ether.Writer
4− (
5− -- * MonadWriter class
6− MonadWriter
7− , writer
8− , tell
9− , listen
10− , pass
11− , listens
12− , censor
13− -- * The Writer monad
14− , Writer
15− , runWriter
16− , execWriter
17− -- * The WriterT monad transformer
18− , WriterT
19− , writerT
20− , runWriterT
21− , execWriterT
22− ) where
23−
24−import Control.Monad.Ether.Handle
25−import Control.Monad.Ether.Writer.Class
26−import Control.Monad.Trans.Ether.Handler
27−import qualified Control.Monad.Writer as T
28−import Data.Functor.Identity
1+module Ether.Writer
2+ (
3+ -- * MonadWriter class
4+ MonadWriter
5+ , writer
6+ , tell
7+ , listen
8+ , pass
9+ , listens
10+ , censor
11+ -- * The Writer monad
12+ , Writer
13+ , runWriter
14+ , execWriter
15+ -- * The WriterT monad transformer
16+ , WriterT
17+ , writerT
18+ , runWriterT
19+ , execWriterT
20+ -- * MonadWriter class (implicit)
21+ , MonadWriter'
22+ , writer'
23+ , tell'
24+ , listen'
25+ , pass'
26+ , listens'
27+ , censor'
28+ -- * The Writer monad (implicit)
29+ , Writer'
30+ , runWriter'
31+ , execWriter'
32+ -- * The WriterT monad transformer (implicit)
33+ , WriterT'
34+ , writerT'
35+ , runWriterT'
36+ , execWriterT'
37+ -- * Internal labels
38+ , TAGGED
39+ , WRITER
40+ ) where
41+
2942import Control.Monad.Signatures (Listen, Pass)
43+import qualified Control.Monad.Trans.Lift.Listen as Lift
44+import qualified Control.Monad.Trans.Lift.Pass as Lift
45+import qualified Control.Monad.Writer as T
3046import Data.Coerce
47+import Data.Functor.Identity
48+
49+import Ether.Handler
50+import Ether.Internal
51+
52+class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
53+
54+ {-# MINIMAL (writer | tell), listen, pass #-}
55+
56+ -- | Embed a simple writer action.
57+ writer :: (a, w) -> m a
58+ writer ~(a, w) = a <$ tell @tag w
59+
60+ -- | Append a value to the accumulator within the monad.
61+ tell :: w -> m ()
62+ tell w = writer @tag ((),w)
63+
64+ -- | Execute an action and add its accumulator
65+ -- to the value of the computation.
66+ listen :: m a -> m (a, w)
67+
68+ -- | Execute an action which returns a value and a function,
69+ -- and return the value, applying the function to the accumulator.
70+ pass :: m (a, w -> w) -> m a
71+
72+instance {-# OVERLAPPABLE #-}
73+ ( Lift.LiftListen t
74+ , Lift.LiftPass t
75+ , Monad (t m)
76+ , MonadWriter tag w m
77+ , Monoid w
78+ ) => MonadWriter tag w (t m) where
79+
80+ writer = Lift.lift . writer @tag
81+ {-# INLINE writer #-}
82+
83+ tell = Lift.lift . tell @tag
84+ {-# INLINE tell #-}
85+
86+ listen = Lift.liftListen (listen @tag)
87+ {-# INLINE listen #-}
88+
89+ pass = Lift.liftPass (pass @tag)
90+ {-# INLINE pass #-}
3191
3292-- | Execute an action and add the result of applying the given function to
3393-- its accumulator to the value of the computation.
@@ -119,3 +179,42 @@ instance
119179 coerce (T.pass @w @(trans m) @a) ::
120180 forall eff a . Pass w (Handler eff trans m) a
121181 {-# INLINE pass #-}
182+
183+type Writer' w = Writer w w
184+
185+runWriter' :: Writer' w a -> (a, w)
186+runWriter' = runWriter
187+
188+execWriter' :: Writer' w a -> w
189+execWriter' = execWriter
190+
191+type WriterT' w = WriterT w w
192+
193+writerT' :: m (a, w) -> WriterT' w m a
194+writerT' = writerT
195+
196+runWriterT' :: WriterT' w m a -> m (a, w)
197+runWriterT' = runWriterT
198+
199+execWriterT' :: Monad m => WriterT' w m a -> m w
200+execWriterT' = execWriterT
201+
202+type MonadWriter' w = MonadWriter w w
203+
204+writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
205+writer' = writer @w
206+
207+tell' :: forall w m . MonadWriter' w m => w -> m ()
208+tell' = tell @w
209+
210+listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
211+listen' = listen @w
212+
213+pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
214+pass' = pass @w
215+
216+listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
217+listens' = listens @w
218+
219+censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
220+censor' = censor @w
test/Regression/T1.hs+2−3
@@ -1,7 +1,6 @@
11module Regression.T1 (test1) where
22
3−import Control.Monad.Ether
4−import Control.Ether.Abbr
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
@@ -10,7 +9,7 @@ data Tag1
109data Tag2
1110
1211testEther
13− :: Ether '[Tag1 --> String, Tag2 --> String] m
12+ :: (MonadReader Tag1 String m, MonadReader Tag2 String m)
1413 => m ((String, String), (String, String))
1514testEther = do
1615 s1 <- ask @Tag1
test/Regression/T10.hs+11−10
@@ -2,22 +2,23 @@ module Regression.T10 (test10) where
22
33import Control.Applicative
44import Data.Functor.Identity
5−import qualified Control.Monad.Ether.Implicit as I
5+
6+import Ether
67
78import Test.Tasty
89import Test.Tasty.QuickCheck
910
10−testEther :: Integer -> I.StateT Integer Maybe [Integer]
11+testEther :: Integer -> StateT' Integer Maybe [Integer]
1112testEther m = range
1213 where
1314 range = liftA2 (:) yield (range <|> pure [])
14− yield = I.stateT $ \n -> do
15− I.guard (n <= m)
15+ yield = stateT' $ \n -> do
16+ guard (n <= m)
1617 Just (n, n + 1)
1718
18−testEther' :: Integer -> I.State Integer [Integer]
19+testEther' :: Integer -> State' Integer [Integer]
1920testEther' m =
20− I.stateT $ Identity . maybe ([], m + 1) id . I.runStateT (testEther m)
21+ stateT' $ Identity . maybe ([], m + 1) id . runStateT' (testEther m)
2122
2223next1 :: Integer -> Integer -> Maybe Integer
2324next1 m n
@@ -32,11 +33,11 @@ range1 m n
3233test10 :: TestTree
3334test10 = testGroup "T10: Alternative instance"
3435 [ testProperty "execStateT works"
35− $ \m n -> I.execStateT (testEther m) n == next1 m n
36+ $ \m n -> execStateT' (testEther m) n == next1 m n
3637 , testProperty "evalStateT works"
37− $ \m n -> I.evalStateT (testEther m) n == range1 m n
38+ $ \m n -> evalStateT' (testEther m) n == range1 m n
3839 , testProperty "execState works"
39− $ \m n -> I.execState (testEther' m) n == m + 1
40+ $ \m n -> execState' (testEther' m) n == m + 1
4041 , testProperty "evalState works"
41− $ \m n -> I.evalState (testEther' m) n == [n..m]
42+ $ \m n -> evalState' (testEther' m) n == [n..m]
4243 ]
test/Regression/T11.hs+4−4
@@ -1,8 +1,8 @@
11module Regression.T11 (test11) where
22
3−import Data.Bool
4−import Control.Monad.Ether
3+import Ether
54
5+import Data.Bool
66import qualified Control.Monad.State as T
77import qualified Control.Monad.Reader as T
88
@@ -28,12 +28,12 @@ model n = zipWith ($) (cycle [id, negate]) [n..]
2828
2929runner1 n
3030 = flip (T.runReader) n
31− . flip (execStateT @STag) []
31+ . flip (execLazyStateT @STag) []
3232 . flip T.evalStateT False
3333
3434runner2 n
3535 = flip T.evalState False
36− . flip (execStateT @STag) []
36+ . flip (execLazyStateT @STag) []
3737 . flip T.runReaderT n
3838
3939test11 :: TestTree
test/Regression/T12.hs+3−4
@@ -1,7 +1,6 @@
11module Regression.T12 (test12) where
22
3−import Control.Monad.Ether.State
4−import Control.Monad.Ether.State.Zoom
3+import Ether
54import Control.Lens
65
76import Test.Tasty
@@ -14,8 +13,8 @@ succState = modify @Foo succ
1413
1514testEther :: (Enum a, MonadState Foo (a, a) m) => m (a, a)
1615testEther = do
17− tagZoom @Foo _1 succState
18− tagZoom @Foo _2 $ modify @Foo pred
16+ Ether.zoom @Foo _1 succState
17+ Ether.zoom @Foo _2 $ modify @Foo pred
1918 get @Foo
2019
2120model :: Enum a => (a, a) -> (a, a)
test/Regression/T2.hs+7−9
@@ -1,20 +1,18 @@
11module Regression.T2 (test2) where
22
3−import Control.Ether.Abbr
4−import qualified Control.Monad.Ether.Implicit as I
5−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
64
75import Test.Tasty
86import Test.Tasty.QuickCheck
97
10−testEther :: Ether '[I.R Integer, I.R Bool] m => m String
11−testEther = I.local (succ :: Integer -> Integer) $ do
12− n :: Integer <- I.asks (*2)
13− b <- I.local not I.ask
8+testEther :: (MonadReader' Integer m, MonadReader' Bool m) => m String
9+testEther = local' (succ :: Integer -> Integer) $ do
10+ n :: Integer <- asks' (*2)
11+ b <- local' not ask'
1412 return (if b then "" else show n)
1513
16−runner1 (n :: Integer) = flip I.runReader n . flip I.runReaderT True
17−runner2 (n :: Integer) = flip I.runReader True . flip I.runReaderT n
14+runner1 (n :: Integer) = flip runReader' n . flip runReaderT' True
15+runner2 (n :: Integer) = flip runReader' True . flip runReaderT' n
1816
1917test2 :: TestTree
2018test2 = testGroup "T2: Implicit tags"
test/Regression/T3.hs+2−3
@@ -1,7 +1,6 @@
11module Regression.T3 (test3) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.Reader as T
76import qualified Control.Monad.State as T
@@ -20,7 +19,7 @@ testMTL = do
2019 return (a * b)
2120
2221testEther
23− :: Ether '[STag --> Int, STag <-> Int, RTag --> Int] m
22+ :: (MonadReader STag Int m, MonadState STag Int m, MonadReader RTag Int m)
2423 => m (Int, Int, Int)
2524testEther = local @RTag (*2) $ do
2625 a_mul_b <- tagAttach @STag testMTL
test/Regression/T4.hs+2−3
@@ -1,14 +1,13 @@
11module Regression.T4 (test4) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
87
98data RTag
109
11−testEther :: Ether '[RTag --> Int] m => m Int
10+testEther :: MonadReader RTag Int m => m Int
1211testEther = ask @RTag
1312
1413runner r
test/Regression/T5.hs+8−11
@@ -1,9 +1,6 @@
11module Regression.T5 (test5) where
22
3−import Control.Ether.Abbr
4−
5−import qualified Control.Monad.Ether.Implicit as I
6−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
74
85import Test.Tasty
96import Test.Tasty.QuickCheck
@@ -16,22 +13,22 @@ incCounter = succ
1613
1714testEther
1815 :: (Num a, Ord a)
19− => Ether '[I.R a, I.S Counter] m
16+ => (MonadReader' a m, MonadState' Counter m)
2017 => m a
2118testEther = do
22− a <- I.ask
19+ a <- ask'
2320 if a <= 0
2421 then do
25− I.put (0 :: Counter)
22+ put' (0 :: Counter)
2623 return 1
2724 else do
28− I.modify incCounter -- overriden in the base case
29− b <- I.runReaderT testEther (a - 1)
30− I.modify incCounter
25+ modify' incCounter -- overriden in the base case
26+ b <- runReaderT' testEther (a - 1)
27+ modify' incCounter
3128 return (a * b)
3229
3330runner :: (Num a, Ord a) => a -> (a, Counter)
34−runner a = I.runState (I.runReaderT testEther a) (0 :: Counter)
31+runner a = runState' (runReaderT' testEther a) (0 :: Counter)
3532
3633factorial :: (Num a, Enum a) => a -> a
3734factorial a = product [1..a]
test/Regression/T6.hs+14−16
@@ -1,10 +1,7 @@
11module Regression.T6 (test6) where
22
3−import Control.Monad
4−import Control.Ether.Abbr
5−
6−import qualified Control.Monad.Ether.Implicit as I
7−import qualified Control.Ether.Implicit.Abbr as I
3+import Data.Function
4+import Ether
85
96import Test.Tasty
107import Test.Tasty.QuickCheck
@@ -17,32 +14,33 @@ data NegativeLog a = NegativeLog a
1714
1815testEther
1916 :: (Floating a, Ord a)
20− => Ether '[I.E DivideByZero, I.E (NegativeLog a)] m
17+ => (MonadExcept' DivideByZero m, MonadExcept' (NegativeLog a) m)
2118 => a -> a -> m a
2219testEther a b = do
23− when (b == 0) (I.throw DivideByZero)
20+ when (b == 0) (throw' DivideByZero)
2421 let d = a / b
25− when (d < 0) (I.throw (NegativeLog d))
22+ when (d < 0) (throw' (NegativeLog d))
2623 return (log d)
2724
28−-- Copied verbatim from "Data.Function" to support @base < 4.8@.
29−(&) :: a -> (a -> b) -> b
30−x & f = f x
31−
3225handleNegativeLog (NegativeLog (x :: Double)) = "nl: " ++ show x
3326handleDivideByZero DivideByZero = "dz"
3427
28+handleT' :: Functor m => (e -> a) -> ExceptT' e m a -> m a
29+handleT' h m = fmap (either h id) (runExceptT' m)
30+
3531runner1 :: Double -> Double -> String
3632runner1 a b = do
3733 (show `fmap` testEther a b)
38− & I.handleT handleNegativeLog
39− & I.handle handleDivideByZero
34+ & handleT' handleNegativeLog
35+ & handleT' handleDivideByZero
36+ & runIdentity
4037
4138runner2 :: Double -> Double -> String
4239runner2 a b = do
4340 (show `fmap` testEther a b)
44− & I.handleT handleDivideByZero
45− & I.handle handleNegativeLog
41+ & handleT' handleDivideByZero
42+ & handleT' handleNegativeLog
43+ & runIdentity
4644
4745logDiv :: Double -> Double -> String
4846logDiv a b
test/Regression/T7.hs+1−1
@@ -3,7 +3,7 @@ module Regression.T7 (test7) where
33import Data.Monoid
44import Control.Monad
55
6−import Control.Monad.Ether
6+import Ether
77import qualified Control.Monad.Writer as T
88
99import Test.Tasty
test/Regression/T8.hs+2−3
@@ -1,7 +1,6 @@
11module Regression.T8 (test8) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.State as T
76
@@ -18,7 +17,7 @@ testMTL2 :: T.MonadState Bool m => m ()
1817testMTL2 = T.modify not
1918
2019testEther
21− :: Ether '[Foo <-> Int, Bar <-> Bool] m
20+ :: (MonadState Foo Int m, MonadState Bar Bool m)
2221 => m String
2322testEther = do
2423 tagAttach @Foo testMTL1
test/Regression/T9.hs+4−5
@@ -1,7 +1,6 @@
11module Regression.T9 (test9) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
@@ -9,16 +8,16 @@ import Test.Tasty.QuickCheck
98data Foo
109data Bar
1110
12−testEther1 :: Ether '[Foo <-> Int] m => m String
11+testEther1 :: MonadState Foo Int m => m String
1312testEther1 = do
1413 modify @Foo negate
1514 gets @Foo show
1615
17−testEther2 :: Ether '[Bar <-> Int] m => m String
16+testEther2 :: MonadState Bar Int m => m String
1817testEther2 = tagReplace @Foo @Bar testEther1
1918
2019testEther
21− :: Ether '[Foo <-> Int, Bar <-> Int] m
20+ :: (MonadState Foo Int m, MonadState Bar Int m)
2221 => m String
2322testEther = do
2423 a <- testEther1