on 3ccb37b help sign in
64 files changed+2122−1941
since splitsnapshots
unifiedsplit
.gitignore+2−17 .travis.yml+18−25 CHANGELOG.md+1−8 README.md+16 bench/Bench.hs+66−63 bench/TupleInstances.hs−9 ether.cabal+45−53 shell.nix−22 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.hs+89 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.hs+121 src/Control/Monad/Ether/Writer/Class.hs+49 src/Control/Monad/Trans/Ether/Handler.hs+177 src/Ether.hs−25 src/Ether/Except.hs−127 src/Ether/Internal.hs−68 src/Ether/Internal/HasLens.hs−24 src/Ether/Internal/TH_TupleInstances.hs−79 src/Ether/Internal/TH_Utils.hs−14 src/Ether/Internal/Tags.hs−18 src/Ether/Internal/TupleInstances.hs−24 src/Ether/Reader.hs−236 src/Ether/State.hs−415 src/Ether/TagDispatch.hs−138 src/Ether/TaggedTrans.hs−206 src/Ether/Writer.hs−287 stack.yaml+2 test/Regression/T1.hs+5−16 test/Regression/T10.hs+10−11 test/Regression/T11.hs+4−4 test/Regression/T12.hs+4−3 test/Regression/T2.hs+9−7 test/Regression/T3.hs+3−2 test/Regression/T4.hs+3−2 test/Regression/T5.hs+11−8 test/Regression/T6.hs+16−14 test/Regression/T7.hs+1−1 test/Regression/T8.hs+3−2 test/Regression/T9.hs+5−4 test/TupleInstances.hs−9
.gitignore+2−17
@@ -1,21 +1,6 @@
1−# Cabal
1+tags
22dist
33dist-newstyle
4+.stack-work
45.cabal-sandbox/
56cabal.sandbox.config
6−cabal.project.local
7−.ghc.environment*
8−
9−# Profiling
10−*.prof
11−
12−# Stack
13−.stack-work
14−
15−# Emacs
16−TAGS
17−.dir-locals.el
18−
19−# Vim
20−tags
21−*.swp
.travis.yml+18−25
@@ -1,31 +1,24 @@
1−language: nix
1+sudo: false
22
3−os:
4− - linux
5− - osx
6−
7−env:
8− - HC=ghc822
9− - HC=ghc844
10− - HC=ghc861
3+cache:
4+ directories:
5+ - $HOME/.stack/
116
127before_install:
13− - curl https://raw.githubusercontent.com/monadfix/nix-cabal/master/nix-cabal -o nix-cabal && chmod u+x nix-cabal
14− - travis_retry ./nix-cabal new-update
8+ - mkdir -p ~/.local/bin
9+ - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
10+ - export PATH=~/.local/bin:$PATH
11+ - stack --version
12+ - stack setup
1513
16−script:
17− - ./nix-cabal new-test ether:regression
18− - ./nix-cabal new-bench ether:bench
14+install:
15+ - stack install --only-dependencies --no-terminal
1916
20−cache:
21− directories:
22− - ~/.cabal
23− - ~/.ghc
17+script:
18+ - stack test ether-suite:regression --no-terminal --ghc-options -Werror
19+ - stack bench ether-suite:bench --no-terminal --ghc-options -Werror
2420
25−matrix:
26− # broken at the moment
27− exclude:
28− - os: osx
29− env: HC=ghc822
30− - os: osx
31− env: HC=ghc861
21+addons:
22+ apt:
23+ packages:
24+ - libgmp-dev
CHANGELOG.md+1−8
@@ -1,20 +1,13 @@
1−0.5.1.0
2−-------
3−
4−* Disable `HasLens` for tuples via cabal flag.
5−
610.5.0.0
72-------
83
94* Support only GHC 8.0 and higher.
105* Use the `TypeApplications` extension to get rid of `Proxy`.
116* Remove `Control.Ether.TH`.
12−* Remove `Control.Ether.Abbr`.
13−* Unify `Dispatch` and `TaggedTrans`.
7+* Unify `Dispatch` and `TaggedTrans` as `Handler`.
148* Better `MonadBase` and `MonadBaseControl` instances.
159* Add flattening for `ReaderT` and `StateT`.
1610* Add zooming for `MonadState`.
17−* Simpler module structure.
1811
19120.4.1.0
2013-------
README.md+16
@@ -2,8 +2,24 @@
22
33[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
44[![Hackage](https://img.shields.io/hackage/v/ether.svg)](https://hackage.haskell.org/package/ether)
5+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/int-index/ether)
56
67
78Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
89and [transformers](https://hackage.haskell.org/package/transformers) with tagged
910monad transformers and classes in a compatible way.
11+
12+## Installation
13+
14+You can install `ether 0.4.0.0`
15+
16+1. using Cabal, from Hackage;
17+2. using Stack, from Stackage;
18+3. using Portage, from Gentoo Haskell Overlay.
19+
20+If unsure, use [Stack](https://github.com/commercialhaskell/stack).
21+
22+## Getting Started
23+
24+To get started, read the introduction on the [homepage](https://int-index.github.io/ether/).
25+If you need help with Ether or if you have any questions about it, ask me in the Gitter chat.
bench/Bench.hs+66−63
@@ -2,13 +2,16 @@
22
33module Main (main) where
44
5−import Control.DeepSeq
6−import qualified Control.Lens as L
5+import Criterion.Main
76import qualified Control.Monad.Reader as M
87import qualified Control.Monad.State as M
9−import Criterion.Main
10−import Ether
11−import TupleInstances ()
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
1215
1316id' :: a -> a
1417id' = id
@@ -68,80 +71,80 @@ run_stateCombinerMTL_flat_9
6871 M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
6972
7073readerCombinerEther_sep_9
71− :: ( MonadReader 1 Int m
72− , MonadReader 2 Int m
73− , MonadReader 3 Int m
74− , MonadReader 4 Int m
75− , MonadReader 5 Int m
76− , MonadReader 6 Int m
77− , MonadReader 7 Int m
78− , MonadReader 8 Int m
79− , MonadReader 9 Int m )
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 )
8083 => m ()
8184readerCombinerEther_sep_9 = rnf <$> sequenceA
82− [ ask @1
83− , ask @2
84− , ask @3
85− , ask @4
86− , ask @5
87− , ask @6
88− , ask @7
89− , ask @8
90− , ask @9 ]
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 ]
9194{-# NOINLINE readerCombinerEther_sep_9 #-}
9295
9396stateCombinerEther_sep_9
94− :: ( MonadState 1 Int m
95− , MonadState 2 Int m
96− , MonadState 3 Int m
97− , MonadState 4 Int m
98− , MonadState 5 Int m
99− , MonadState 6 Int m
100− , MonadState 7 Int m
101− , MonadState 8 Int m
102− , MonadState 9 Int m )
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 )
103106 => m ()
104107stateCombinerEther_sep_9 = do
105− modify @1 id'
106− modify @2 id'
107− modify @3 id'
108− modify @4 id'
109− modify @5 id'
110− modify @6 id'
111− modify @7 id'
112− modify @8 id'
113− modify @9 id'
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'
114117 rnf <$> sequenceA
115− [ get @1
116− , get @2
117− , get @3
118− , get @4
119− , get @5
120− , get @6
121− , get @7
122− , get @8
123− , get @9 ]
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 ]
124127{-# NOINLINE stateCombinerEther_sep_9 #-}
125128
126129run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
127130run_readerCombinerEther_nested_9
128131 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
129− = flip (runReader @9) a1
130− . flip (runReaderT @8) a2
131− . flip (runReaderT @7) a3
132− . flip (runReaderT @6) a4
133− . flip (runReaderT @5) a5
134− . flip (runReaderT @4) a6
135− . flip (runReaderT @3) a7
136− . flip (runReaderT @2) a8
137− . flip (runReaderT @1) 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
138141 $ readerCombinerEther_sep_9
139142
140143run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
141144run_readerCombinerEther_flatten_9
142145 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
143146 =
144− runReaders
147+ E.F.runReader
145148 readerCombinerEther_sep_9
146149 ( Tagged @1 a9,
147150 Tagged @2 a8,
@@ -156,12 +159,12 @@ run_readerCombinerEther_flatten_9
156159run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
157160run_readerCombinerEther_flattenhalf_9
158161 (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
159− flip runReaders
162+ flip E.F.runReader
160163 ( Tagged @1 a9,
161164 Tagged @2 a8,
162165 Tagged @3 a7,
163166 Tagged @4 a6 ) .
164− flip runReadersT
167+ flip E.F.runReaderT
165168 ( Tagged @5 a5,
166169 Tagged @6 a4,
167170 Tagged @7 a3,
@@ -175,7 +178,7 @@ run_stateCombinerEther_flatten_9 ::
175178run_stateCombinerEther_flatten_9
176179 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
177180 =
178− runStates
181+ E.F.runState
179182 stateCombinerEther_sep_9
180183 ( Tagged @1 a9,
181184 Tagged @2 a8,
bench/TupleInstances.hsdeleted−9
@@ -1,9 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module TupleInstances () where
5−
6−#ifdef DISABLE_TUP_INSTANCES
7−import Ether.Internal (makeTupleInstancesHasLens)
8−makeTupleInstancesHasLens [4,5,9]
9−#endif
ether.cabal+45−53
@@ -1,17 +1,21 @@
1−cabal-version: 2.2
21name: ether
3−version: 0.5.2.0
2+version: 0.5.0.0
43synopsis: Monad transformers and classes
5−description: Lib
6−license: BSD-3-Clause
7−-- ^ unfortunately have to change this line due to the issue with cabal2nix
8−license-file: LICENSE
4+description:
5+ Ether is a Haskell library that extends @mtl@ and @transformers@ with
6+ tagged monad transformers and classes in a compatible way.
7+
8+ Introduction <https://int-index.github.io/ether/>
9+
910category: Control
11+license: BSD3
12+license-file: LICENSE
1013author: Vladislav Zavialov
1114maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
1215homepage: https://int-index.github.io/ether/
1316bug-reports: https://github.com/int-index/ether/issues
1417build-type: Simple
18+cabal-version: >=1.18
1519extra-source-files: CHANGELOG.md
1620
1721source-repository head
@@ -20,48 +24,49 @@ source-repository head
2024 location: git@github.com:int-index/ether.git
2125
2226
23−flag disable-tup-instances
24−
25− description:
26− Disable auto-generated 'HasLens' instances for tuples. The reason one
27− might want to do this is to reduce the size of .hi-files, as well as the
28− time and memory GHC needs to build Ether. To recover flattening with
29− tuples, use 'Ether.Internal.makeTupleInstancesHasLens' at specific tuple
30− sizes you need in your application.
31−
32− This is a build-time performance hack, enable this flag at your own risk.
33−
34− default: False
35− manual: True
36−
3727library
3828
3929 exposed-modules:
40− Ether
41− Ether.Reader
42− Ether.State
43− Ether.Writer
44− Ether.Except
45− Ether.TaggedTrans
46− Ether.TagDispatch
47− Ether.Internal
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
4858
4959 other-modules:
50− Ether.Internal.Tags
51− Ether.Internal.HasLens
52− Ether.Internal.TH_Utils
53− Ether.Internal.TH_TupleInstances
54− Ether.Internal.TupleInstances
60+ Control.Monad.Ether.State.Common
5561
5662 build-depends:
57− base >=4.9 && <4.13,
58− transformers >=0.5.2.0,
59− transformers-lift >=0.2.0.1,
60− mtl >=2.2.2,
63+ base >=4.9 && <4.11,
64+ transformers >=0.4.2,
65+ transformers-lift >=0.1.0.1,
66+ mtl >=2.2.1,
6167 mmorph >=1.0.4,
6268 monad-control >=1.0.0.4,
6369 transformers-base >=0.4.4,
64− writer-cps-mtl >= 0.1.1.4,
6570 exceptions >=0.8,
6671 template-haskell >=2.11,
6772 tagged >=0.8.5,
@@ -101,13 +106,10 @@ library
101106 ghc-options:
102107 -Wall -O2
103108
104− if flag(disable-tup-instances)
105− cpp-options: -DDISABLE_TUP_INSTANCES
106−
107109test-suite regression
108110
109111 build-depends:
110− base >=4.9 && <4.13,
112+ base >=4.9 && <4.11,
111113 transformers >=0.4.2,
112114 mtl >=2.2.1,
113115 tasty >=0.10,
@@ -121,7 +123,6 @@ test-suite regression
121123 Regression.hs
122124
123125 other-modules:
124− TupleInstances
125126 Regression.T1
126127 Regression.T2
127128 Regression.T3
@@ -172,14 +173,11 @@ test-suite regression
172173 ghc-options:
173174 -Wall -fno-warn-missing-signatures
174175
175− if flag(disable-tup-instances)
176− cpp-options: -DDISABLE_TUP_INSTANCES
177−
178176
179177benchmark bench
180178
181179 build-depends:
182− base >=4.9 && <4.13,
180+ base >=4.9 && <4.11,
183181 mtl >=2.2.1,
184182 transformers >=0.4.2,
185183 criterion >=1.1,
@@ -190,9 +188,6 @@ benchmark bench
190188 main-is:
191189 Bench.hs
192190
193− other-modules:
194− TupleInstances
195−
196191 type:
197192 exitcode-stdio-1.0
198193
@@ -232,6 +227,3 @@ benchmark bench
232227
233228 ghc-prof-options:
234229 -fprof-auto
235−
236− if flag(disable-tup-instances)
237− cpp-options: -DDISABLE_TUP_INSTANCES
shell.nixdeleted−22
@@ -1,22 +0,0 @@
1−{ pkgs ? import <nixpkgs> {},
2− hc ? "ghc844"
3−}:
4−
5−pkgs.stdenv.mkDerivation rec {
6− name = "ether";
7− buildInputs = [
8− pkgs.haskell.compiler.${hc}
9− pkgs.git
10− pkgs.zlib
11− pkgs.cabal-install
12− pkgs.pkgconfig
13− ];
14− shellHook = ''
15− export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH
16− export LANG=en_US.UTF-8
17− '';
18− LOCALE_ARCHIVE =
19− if pkgs.stdenv.isLinux
20− then "${pkgs.glibcLocales}/lib/locale/locale-archive"
21− else "";
22−}
src/Control/Ether/Abbr.hsnew file+61
@@ -0,0 +1,61 @@
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.hsnew file+23
@@ -0,0 +1,23 @@
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.hsnew file+142
@@ -0,0 +1,142 @@
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.hsnew file+13
@@ -0,0 +1,13 @@
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.hsnew file+89
@@ -0,0 +1,89 @@
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
24+import qualified Control.Monad.Except as T
25+import Control.Monad.Signatures (Catch)
26+import Data.Functor.Identity
27+import Data.Coerce
28+
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)
32+
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)
36+
37+-- | Encode type-level information for 'ExceptT'.
38+data EXCEPT
39+
40+-- | The parameterizable exception monad.
41+--
42+-- Computations are either exceptions or normal values.
43+--
44+-- The 'return' function returns a normal value, while '>>=' exits on
45+-- the first exception.
46+type Except tag e = ExceptT tag e Identity
47+
48+-- | The exception monad transformer.
49+--
50+-- The 'return' function returns a normal value, while '>>=' exits on
51+-- the first exception.
52+type ExceptT tag e = Handler (TAGGED EXCEPT tag) (T.ExceptT e)
53+
54+-- | Runs an 'Except' and returns either an exception or a normal value.
55+runExcept :: forall tag e a . Except tag e a -> Either e a
56+runExcept = coerce (T.runExcept @e @a)
57+
58+-- | Runs an 'ExceptT' and returns either an exception or a normal value.
59+runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
60+runExceptT = coerce (T.runExceptT @e @m @a)
61+
62+-- | Constructor for computations in the exception monad transformer.
63+exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
64+exceptT = coerce (T.ExceptT @e @m @a)
65+
66+type instance HandleSuper EXCEPT e trans = ()
67+type instance HandleConstraint EXCEPT e trans m =
68+ T.MonadError e (trans m)
69+
70+instance Handle EXCEPT e (T.ExceptT e) where
71+ handling r = r
72+ {-# INLINE handling #-}
73+
74+instance
75+ ( Handle EXCEPT e trans
76+ , Monad m, Monad (trans m)
77+ ) => MonadExcept tag e (Handler (TAGGED EXCEPT tag) trans m)
78+ where
79+ throw =
80+ handling @EXCEPT @e @trans @m $
81+ coerce (T.throwError @e @(trans m) @a) ::
82+ forall dp a . e -> Handler dp trans m a
83+ {-# INLINE throw #-}
84+
85+ catch =
86+ handling @EXCEPT @e @trans @m $
87+ coerce (T.catchError @e @(trans m) @a) ::
88+ forall dp a . Catch e (Handler dp trans m) a
89+ {-# INLINE catch #-}
src/Control/Monad/Ether/Except/Class.hsnew file+29
@@ -0,0 +1,29 @@
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.hsnew file+35
@@ -0,0 +1,35 @@
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.hsnew file+13
@@ -0,0 +1,13 @@
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.hsnew file+58
@@ -0,0 +1,58 @@
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.hsnew file+57
@@ -0,0 +1,57 @@
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.hsnew file+7
@@ -0,0 +1,7 @@
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.hsnew file+82
@@ -0,0 +1,82 @@
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.hsnew file+82
@@ -0,0 +1,82 @@
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.hsnew file+77
@@ -0,0 +1,77 @@
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.hsnew file+128
@@ -0,0 +1,128 @@
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 dp a . Local r (Handler dp 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 dp a . (r -> a) -> Handler dp 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 ': dps) trans m)
112+ where
113+
114+ ask =
115+ handling @READER @payload @trans @m $
116+ (coerce :: forall dp a .
117+ trans m a ->
118+ Handler dp 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 dp a .
125+ (trans m a -> trans m a) ->
126+ (Handler dp trans m a -> Handler dp trans m a))
127+ (T.local (over (lensOf @tag @payload @r) f))
128+ {-# INLINE local #-}
src/Control/Monad/Ether/Reader/Class.hsnew file+77
@@ -0,0 +1,77 @@
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 dps trans m)
55+ ) => MonadReader tag r (Handler (dp ': dps) trans (m :: K.Type -> K.Type))
56+ where
57+
58+ ask =
59+ (coerce ::
60+ Handler dps trans m r ->
61+ Handler (dp ': dps) trans m r)
62+ (ask @tag)
63+ {-# INLINE ask #-}
64+
65+ local =
66+ (coerce :: forall a .
67+ Lift.Local r (Handler dps trans m) a ->
68+ Lift.Local r (Handler (dp ': dps) trans m) a)
69+ (local @tag)
70+ {-# INLINE local #-}
71+
72+ reader =
73+ (coerce :: forall a .
74+ ((r -> a) -> Handler dps trans m a) ->
75+ ((r -> a) -> Handler (dp ': dps) trans m a))
76+ (reader @tag)
77+ {-# INLINE reader #-}
src/Control/Monad/Ether/Reader/Flatten.hsnew file+29
@@ -0,0 +1,29 @@
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.hsnew file+7
@@ -0,0 +1,7 @@
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.hsnew file+74
@@ -0,0 +1,74 @@
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 dps trans m)
52+ ) => MonadState tag s (Handler (dp ': dps) trans (m :: K.Type -> K.Type))
53+ where
54+
55+ get =
56+ (coerce ::
57+ Handler dps trans m s ->
58+ Handler (dp ': dps) trans m s)
59+ (get @tag)
60+ {-# INLINE get #-}
61+
62+ put =
63+ (coerce ::
64+ (s -> Handler dps trans m ()) ->
65+ (s -> Handler (dp ': dps) trans m ()))
66+ (put @tag)
67+ {-# INLINE put #-}
68+
69+ state =
70+ (coerce :: forall a .
71+ ((s -> (a, s)) -> Handler dps trans m a) ->
72+ ((s -> (a, s)) -> Handler (dp ': dps) trans m a))
73+ (state @tag)
74+ {-# INLINE state #-}
src/Control/Monad/Ether/State/Common.hsnew file+90
@@ -0,0 +1,90 @@
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 dp a . (s -> (a, s)) -> Handler dp 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 ': dps) trans m)
66+ where
67+
68+ get =
69+ handling @STATE @payload @trans @m $
70+ (coerce :: forall dp a .
71+ trans m a ->
72+ Handler dp 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 dp a .
79+ trans m a ->
80+ Handler dp 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 dp a .
87+ trans m a ->
88+ Handler dp trans m a)
89+ (T.state (lensOf @tag @payload @s f))
90+ {-# INLINE state #-}
src/Control/Monad/Ether/State/Flatten.hsnew file+29
@@ -0,0 +1,29 @@
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.hsnew file+87
@@ -0,0 +1,87 @@
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.hsnew file+87
@@ -0,0 +1,87 @@
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.hsnew file+48
@@ -0,0 +1,48 @@
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 dp r a .
43+ (r -> m a) ->
44+ (r -> Handler dp trans m a))
45+ (state @tag . l)
46+ where
47+ Lens l = reflect (Proxy :: Proxy z)
48+ {-# INLINE state #-}
src/Control/Monad/Ether/TagAttach.hsnew file+66
@@ -0,0 +1,66 @@
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.hsnew file+61
@@ -0,0 +1,61 @@
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.hsnew file+121
@@ -0,0 +1,121 @@
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
29+import Control.Monad.Signatures (Listen, Pass)
30+import Data.Coerce
31+
32+-- | Execute an action and add the result of applying the given function to
33+-- its accumulator to the value of the computation.
34+listens :: forall tag w m a b . MonadWriter tag w m => (w -> b) -> m a -> m (a, b)
35+listens f m = do
36+ ~(a, w) <- listen @tag m
37+ return (a, f w)
38+
39+-- | Execute an action and apply a function to its accumulator.
40+censor :: forall tag w m a . MonadWriter tag w m => (w -> w) -> m a -> m a
41+censor f m = pass @tag $ do
42+ a <- m
43+ return (a, f)
44+
45+-- | Encode type-level information for 'WriterT'.
46+data WRITER
47+
48+-- | The parametrizable writer monad.
49+--
50+-- Computations can accumulate a monoid value.
51+--
52+-- The 'return' function produces the output 'mempty', while '>>=' combines
53+-- the outputs of the subcomputations using 'mappend'.
54+type Writer tag w = WriterT tag w Identity
55+
56+-- | The writer monad transformer.
57+--
58+-- The 'return' function produces the output 'mempty', while '>>=' combines
59+-- the outputs of the subcomputations using 'mappend'.
60+type WriterT tag w = Handler (TAGGED WRITER tag) (T.WriterT w)
61+
62+-- | Constructor for computations in the writer monad transformer.
63+writerT :: forall tag w m a . m (a, w) -> WriterT tag w m a
64+writerT = coerce (T.WriterT @w @m @a)
65+
66+-- | Runs a 'WriterT' and returns both the normal value
67+-- and the final accumulator.
68+runWriterT :: forall tag w m a . WriterT tag w m a -> m (a, w)
69+runWriterT = coerce (T.runWriterT @w @m @a)
70+
71+-- | Runs a 'Writer' and returns both the normal value
72+-- and the final accumulator.
73+runWriter :: forall tag w a . Writer tag w a -> (a, w)
74+runWriter = coerce (T.runWriter @w @a)
75+
76+-- | Runs a 'WriterT' and returns the final accumulator,
77+-- discarding the normal value.
78+execWriterT :: forall tag w m a . Monad m => WriterT tag w m a -> m w
79+execWriterT = coerce (T.execWriterT @m @w @a)
80+
81+-- | Runs a 'Writer' and returns the final accumulator,
82+-- discarding the normal value.
83+execWriter :: forall tag w a . Writer tag w a -> w
84+execWriter = coerce (T.execWriter @w @a)
85+
86+type instance HandleSuper WRITER w trans = Monoid w
87+type instance HandleConstraint WRITER w trans m =
88+ T.MonadWriter w (trans m)
89+
90+instance Monoid w => Handle WRITER w (T.WriterT w) where
91+ handling r = r
92+ {-# INLINE handling #-}
93+
94+instance
95+ ( Handle WRITER w trans
96+ , Monad m, Monad (trans m)
97+ ) => MonadWriter tag w (Handler (TAGGED WRITER tag) trans m)
98+ where
99+
100+ writer =
101+ handling @WRITER @w @trans @m $
102+ coerce (T.writer @w @(trans m) @a) ::
103+ forall dp a . (a, w) -> Handler dp trans m a
104+ {-# INLINE writer #-}
105+
106+ tell =
107+ handling @WRITER @w @trans @m $
108+ coerce (T.tell @w @(trans m))
109+ {-# INLINE tell #-}
110+
111+ listen =
112+ handling @WRITER @w @trans @m $
113+ coerce (T.listen @w @(trans m) @a) ::
114+ forall dp a . Listen w (Handler dp trans m) a
115+ {-# INLINE listen #-}
116+
117+ pass =
118+ handling @WRITER @w @trans @m $
119+ coerce (T.pass @w @(trans m) @a) ::
120+ forall dp a . Pass w (Handler dp trans m) a
121+ {-# INLINE pass #-}
src/Control/Monad/Ether/Writer/Class.hsnew file+49
@@ -0,0 +1,49 @@
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/Control/Monad/Trans/Ether/Handler.hsnew file+177
@@ -0,0 +1,177 @@
1+module Control.Monad.Trans.Ether.Handler
2+ ( Handler(..)
3+ ) where
4+
5+import Control.Applicative
6+import Control.Monad (MonadPlus)
7+import Control.Monad.Fix (MonadFix)
8+import Control.Monad.Trans.Class (MonadTrans, lift)
9+import Control.Monad.IO.Class (MonadIO)
10+import Control.Monad.Morph (MFunctor, MMonad)
11+import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
12+
13+import qualified Control.Monad.Base as MB
14+import qualified Control.Monad.Trans.Control as MC
15+
16+import qualified Control.Monad.Trans.Lift.StT as Lift
17+import qualified Control.Monad.Trans.Lift.Local as Lift
18+import qualified Control.Monad.Trans.Lift.Catch as Lift
19+import qualified Control.Monad.Trans.Lift.Listen as Lift
20+import qualified Control.Monad.Trans.Lift.Pass as Lift
21+import qualified Control.Monad.Trans.Lift.CallCC as Lift
22+
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
28+
29+import GHC.Generics (Generic)
30+import Data.Coerce (coerce)
31+
32+newtype Handler dp trans m a = Handler (trans m a)
33+ deriving
34+ ( Generic
35+ , Functor, Applicative, Alternative, Monad, MonadPlus
36+ , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
37+ , MonadThrow, MonadCatch, MonadMask )
38+
39+type Pack dp trans m a = trans m a -> Handler dp trans m a
40+
41+type Unpack dp trans m a = Handler dp trans m a -> trans m a
42+
43+instance
44+ ( MB.MonadBase b (trans m)
45+ ) => MB.MonadBase b (Handler dp trans m)
46+ where
47+ liftBase =
48+ (coerce :: forall a .
49+ (b a -> trans m a) ->
50+ (b a -> Handler dp trans m a))
51+ MB.liftBase
52+
53+instance
54+ ( MC.MonadTransControl trans
55+ ) => MC.MonadTransControl (Handler dp trans)
56+ where
57+ type StT (Handler dp trans) a = MC.StT trans a
58+ liftWith = MC.defaultLiftWith
59+ (coerce :: Pack dp trans m a)
60+ (coerce :: Unpack dp trans m a)
61+ restoreT = MC.defaultRestoreT
62+ (coerce :: Pack dp trans m a)
63+
64+type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
65+
66+newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
67+
68+coerceLiftBaseWith ::
69+ LiftBaseWith b (trans m) a ->
70+ LiftBaseWith b (Handler dp trans m) a
71+coerceLiftBaseWith lbw =
72+ unLBW (coerce (LBW lbw))
73+{-# INLINE coerceLiftBaseWith #-}
74+
75+instance
76+ ( MC.MonadBaseControl b (trans m)
77+ ) => MC.MonadBaseControl b (Handler dp trans m)
78+ where
79+ type StM (Handler dp trans m) a = MC.StM (trans m) a
80+
81+ liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
82+ {-# INLINE liftBaseWith #-}
83+
84+ restoreM =
85+ (coerce :: forall a .
86+ (MC.StM (trans m) a -> trans m a) ->
87+ (MC.StM (trans m) a -> Handler dp trans m a))
88+ MC.restoreM
89+ {-# INLINE restoreM #-}
90+
91+type instance Lift.StT (Handler dp trans) a = Lift.StT trans a
92+
93+instance Lift.LiftLocal trans => Lift.LiftLocal (Handler dp trans) where
94+ liftLocal =
95+ Lift.defaultLiftLocal
96+ (coerce :: Pack dp trans m a)
97+ (coerce :: Unpack dp trans m a)
98+
99+instance Lift.LiftCatch trans => Lift.LiftCatch (Handler dp trans) where
100+ liftCatch =
101+ Lift.defaultLiftCatch
102+ (coerce :: Pack dp trans m a)
103+ (coerce :: Unpack dp trans m a)
104+
105+instance Lift.LiftListen trans => Lift.LiftListen (Handler dp trans) where
106+ liftListen =
107+ Lift.defaultLiftListen
108+ (coerce :: Pack dp trans m a)
109+ (coerce :: Unpack dp trans m a)
110+
111+instance Lift.LiftPass trans => Lift.LiftPass (Handler dp trans) where
112+ liftPass =
113+ Lift.defaultLiftPass
114+ (coerce :: Pack dp trans m a)
115+ (coerce :: Unpack dp trans m a)
116+
117+instance Lift.LiftCallCC trans => Lift.LiftCallCC (Handler dp trans) where
118+ liftCallCC =
119+ Lift.defaultLiftCallCC
120+ (coerce :: Pack dp trans m a)
121+ (coerce :: Unpack dp trans m a)
122+ liftCallCC' =
123+ Lift.defaultLiftCallCC'
124+ (coerce :: Pack dp trans m a)
125+ (coerce :: Unpack dp trans m a)
126+
127+
128+-- Instances for mtl classes
129+
130+instance {-# OVERLAPPABLE #-}
131+ ( Class.MonadCont m
132+ , Lift.LiftCallCC trans
133+ , Monad (trans m)
134+ ) => Class.MonadCont (Handler dp trans m)
135+ where
136+ callCC = Lift.liftCallCC' Class.callCC
137+
138+instance {-# OVERLAPPABLE #-}
139+ ( Class.MonadReader r m
140+ , Lift.LiftLocal trans
141+ , Monad (trans m)
142+ ) => Class.MonadReader r (Handler dp trans m)
143+ where
144+ ask = lift Class.ask
145+ local = Lift.liftLocal Class.ask Class.local
146+ reader = lift . Class.reader
147+
148+instance {-# OVERLAPPABLE #-}
149+ ( Class.MonadState s m
150+ , MonadTrans trans
151+ , Monad (trans m)
152+ ) => Class.MonadState s (Handler dp trans m)
153+ where
154+ get = lift Class.get
155+ put = lift . Class.put
156+ state = lift . Class.state
157+
158+instance {-# OVERLAPPABLE #-}
159+ ( Class.MonadWriter w m
160+ , Lift.LiftListen trans
161+ , Lift.LiftPass trans
162+ , Monad (trans m)
163+ ) => Class.MonadWriter w (Handler dp trans m)
164+ where
165+ writer = lift . Class.writer
166+ tell = lift . Class.tell
167+ listen = Lift.liftListen Class.listen
168+ pass = Lift.liftPass Class.pass
169+
170+instance {-# OVERLAPPABLE #-}
171+ ( Class.MonadError e m
172+ , Lift.LiftCatch trans
173+ , Monad (trans m)
174+ ) => Class.MonadError e (Handler dp trans m)
175+ where
176+ throwError = lift . Class.throwError
177+ catchError = Lift.liftCatch Class.catchError
src/Ether.hsdeleted−25
@@ -1,25 +0,0 @@
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.TaggedTrans
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.TaggedTrans
src/Ether/Except.hsdeleted−127
@@ -1,127 +0,0 @@
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−
30−import qualified Control.Monad.Except as T
31−import Control.Monad.Signatures (Catch)
32−import qualified Control.Monad.Trans.Lift.Catch as Lift
33−import Data.Coerce
34−import Data.Functor.Identity
35−
36−import Ether.TaggedTrans
37−import Ether.Internal
38−
39−class Monad m => MonadExcept tag e m | m tag -> e where
40−
41− -- | Is used within a monadic computation to begin exception processing.
42− throw :: e -> m a
43−
44− -- | A TaggedTrans 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− throw = Lift.lift . throw @tag
54− catch = Lift.liftCatch (catch @tag)
55−
56−-- | Encode type-level information for 'ExceptT'.
57−data EXCEPT
58−
59−-- | The parameterizable exception monad.
60−--
61−-- Computations are either exceptions or normal values.
62−--
63−-- The 'return' function returns a normal value, while '>>=' exits on
64−-- the first exception.
65−type Except tag e = ExceptT tag e Identity
66−
67−-- | The exception monad transformer.
68−--
69−-- The 'return' function returns a normal value, while '>>=' exits on
70−-- the first exception.
71−type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
72−
73−-- | Runs an 'Except' and returns either an exception or a normal value.
74−runExcept :: forall tag e a . Except tag e a -> Either e a
75−runExcept = coerce (T.runExcept @e @a)
76−
77−-- | Runs an 'ExceptT' and returns either an exception or a normal value.
78−runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
79−runExceptT = coerce (T.runExceptT @e @m @a)
80−
81−-- | Constructor for computations in the exception monad transformer.
82−exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
83−exceptT = coerce (T.ExceptT @e @m @a)
84−
85−type instance HandleSuper EXCEPT e trans = ()
86−type instance HandleConstraint EXCEPT e trans m =
87− T.MonadError e (trans m)
88−
89−instance Handle EXCEPT e (T.ExceptT e) where
90− handling r = r
91−
92−instance
93− ( Handle EXCEPT e trans
94− , Monad m, Monad (trans m)
95− ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
96− where
97−
98− throw =
99− handling @EXCEPT @e @trans @m $
100− coerce (T.throwError @e @(trans m) @a) ::
101− forall eff a . e -> TaggedTrans eff trans m a
102−
103− catch =
104− handling @EXCEPT @e @trans @m $
105− coerce (T.catchError @e @(trans m) @a) ::
106− forall eff a . Catch e (TaggedTrans eff trans m) a
107−
108−type MonadExcept' e = MonadExcept e e
109−
110−throw' :: forall e m a . MonadExcept' e m => e -> m a
111−throw' = throw @e
112−
113−catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
114−catch' = catch @e
115−
116−type Except' e = Except e e
117−
118−runExcept' :: Except' e a -> Either e a
119−runExcept' = runExcept
120−
121−type ExceptT' e = ExceptT e e
122−
123−exceptT' :: m (Either e a) -> ExceptT' e m a
124−exceptT' = exceptT
125−
126−runExceptT' :: ExceptT' e m a -> m (Either e a)
127−runExceptT' = runExceptT
src/Ether/Internal.hsdeleted−68
@@ -1,68 +0,0 @@
1−module Ether.Internal
2− ( Tagged(..)
3− , TagsK
4− , Tags
5− , HasLens(..)
6− , LensLike
7− , Lens
8− , Lens'
9− , ReifiedLens(..)
10− , ReifiedLens'
11− , view
12− , over
13− , HList(..)
14− , KindOf
15− , TAGGED
16− , HandleSuper
17− , HandleConstraint
18− , Handle(..)
19− , makeTupleInstancesHasLens
20− ) where
21−
22−import Control.Applicative
23−import Data.Coerce
24−import Data.Functor.Identity
25−import Data.Kind
26−import Data.Tagged
27−import GHC.Exts (Constraint)
28−
29−import Ether.Internal.HasLens
30−import Ether.Internal.Tags
31−import Ether.Internal.TH_TupleInstances (makeTupleInstancesHasLens)
32−import Ether.Internal.TupleInstances ()
33−
34−data TAGGED e t
35−
36−type K_Monad = Type -> Type
37−
38−type K_Trans = K_Monad -> K_Monad
39−
40−type family
41− HandleSuper
42− (eff :: keff)
43− (p :: kp)
44− (trans :: K_Trans)
45− :: Constraint
46−
47−type family
48− HandleConstraint
49− (eff :: keff)
50− (p :: kp)
51− (trans :: K_Trans) (m :: K_Monad)
52− :: Constraint
53−
54−class
55− HandleSuper eff p trans =>
56− Handle eff p (trans :: K_Trans) | eff trans -> p
57− where
58− handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
59−
60−newtype ReifiedLens s t a b = Lens (Lens s t a b)
61−
62−type ReifiedLens' s a = ReifiedLens s s a a
63−
64−view :: LensLike (Const a) s t a b -> s -> a
65−view l = coerce (l Const)
66−
67−over :: LensLike Identity s t a b -> (a -> b) -> s -> t
68−over = coerce
src/Ether/Internal/HasLens.hsdeleted−24
@@ -1,24 +0,0 @@
1−module Ether.Internal.HasLens
2− ( LensLike
3− , Lens
4− , Lens'
5− , HasLens(..)
6− ) where
7−
8−import Data.Tagged
9−import Data.Coerce
10−
11−type LensLike f s t a b = (a -> f b) -> s -> f t
12−
13−type Lens s t a b = forall f. Functor f => LensLike f s t a b
14−
15−type Lens' s a = Lens s s a a
16−
17−class HasLens tag outer inner | tag outer -> inner where
18− lensOf :: Lens' outer inner
19−
20−instance HasLens a a a where
21− lensOf = id
22−
23−instance HasLens t (Tagged t a) a where
24− lensOf = \f -> fmap coerce . f . coerce
src/Ether/Internal/TH_TupleInstances.hsdeleted−79
@@ -1,79 +0,0 @@
1−module Ether.Internal.TH_TupleInstances
2− ( makeTupleInstancesTagsK
3− , makeTupleInstancesTags
4− , makeTupleInstancesHasLens
5− ) where
6−
7−import Data.Tagged
8−import Data.Traversable
9−import Data.List as List
10−import qualified Language.Haskell.TH as TH
11−
12−import Ether.Internal.HasLens
13−import Ether.Internal.Tags
14−import Ether.Internal.TH_Utils
15−
16−makeTupleInstancesTagsK :: TH.DecsQ
17−makeTupleInstancesTagsK = do
18− for [2..tupCount] $ \n -> do
19− let
20− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
21− (\k -> TH.ConT ''Tagged `TH.AppT`
22− TH.VarT (tagName k) `TH.AppT`
23− TH.VarT (varName k)) <$> [0..n-1]
24− tagsList = List.foldr
25− (\a b -> TH.PromotedConsT `TH.AppT` a `TH.AppT` b)
26− TH.PromotedNilT
27− (TH.AppT (TH.ConT ''KindOf) . TH.VarT . tagName <$> [0..n-1])
28− return $
29− TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy] tagsList)
30−
31−makeTupleInstancesTags :: TH.DecsQ
32−makeTupleInstancesTags = do
33− for [2..tupCount] $ \n -> do
34− let
35− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
36− (\k -> TH.ConT ''Tagged `TH.AppT`
37− TH.VarT (tagName k) `TH.AppT`
38− TH.VarT (varName k)) <$> [0..n-1]
39− tagsList = List.foldr
40− (\a b -> TH.PromotedT 'HCons `TH.AppT` a `TH.AppT` b)
41− (TH.PromotedT 'HNil)
42− (TH.VarT . tagName <$> [0..n-1])
43− return $
44− TH.TySynInstD ''Tags (TH.TySynEqn [tupTy] tagsList)
45−
46−makeTupleInstancesHasLens :: [Int] -> TH.DecsQ
47−makeTupleInstancesHasLens range = List.concat <$> do
48− for range $ \n ->
49− for [0..n-1] $ \k -> do
50− let
51− tag = TH.mkName "tag"
52− prev = varName <$> [0..k-1]
53− cur = varName k
54− next = varName <$> [k+1..n-1]
55− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
56− ( map TH.VarT prev ++
57− [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
58− map TH.VarT next )
59− let
60− cur' = TH.mkName "x"
61− f = TH.mkName "f"
62− return $
63− TH.InstanceD Nothing []
64− (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
65− [ TH.FunD 'lensOf
66− [ TH.Clause
67− [TH.VarP f, TH.TupP
68− ( map TH.VarP prev ++
69− [TH.ConP 'Tagged [TH.VarP cur]] ++
70− map TH.VarP next )]
71− (TH.NormalB $
72− TH.VarE 'fmap `TH.AppE`
73− (TH.LamE [TH.VarP cur']
74− (TH.TupE
75− ( map TH.VarE prev ++
76− [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
77− map TH.VarE next ))) `TH.AppE`
78− (TH.VarE f `TH.AppE` TH.VarE cur) )
79− [] ] ]
src/Ether/Internal/TH_Utils.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Ether.Internal.TH_Utils
2− ( tupCount
3− , varName
4− , tagName
5− ) where
6−
7−import qualified Language.Haskell.TH as TH
8−
9−tupCount :: Int
10−tupCount = 62
11−
12−varName, tagName :: Int -> TH.Name
13−varName k = TH.mkName ('a' : show k)
14−tagName k = TH.mkName ('t' : show k)
src/Ether/Internal/Tags.hsdeleted−18
@@ -1,18 +0,0 @@
1−module Ether.Internal.Tags
2− ( Tags
3− , TagsK
4− , HList(..)
5− , KindOf
6− ) where
7−
8−import Data.Kind
9−
10−data HList xs where
11− HNil :: HList '[]
12− HCons :: x -> HList xs -> HList (x ': xs)
13−
14−type KindOf (a :: k) = k
15−
16−type family TagsK (p :: Type) :: [Type]
17−type family Tags (p :: Type) :: HList (TagsK p)
18−
src/Ether/Internal/TupleInstances.hsdeleted−24
@@ -1,24 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module Ether.Internal.TupleInstances () where
5−
6−import Data.Tagged
7−import Ether.Internal.Tags
8−import Ether.Internal.TH_TupleInstances
9−
10−type instance TagsK () = '[]
11−type instance TagsK (Tagged t a) = '[KindOf t]
12−type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
13−
14−makeTupleInstancesTagsK
15−
16−type instance Tags () = 'HNil
17−type instance Tags (Tagged t a) = 'HCons t 'HNil
18−type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
19−
20−makeTupleInstancesTags
21−
22−#ifndef DISABLE_TUP_INSTANCES
23−makeTupleInstancesHasLens [2..62]
24−#endif
src/Ether/Reader.hsdeleted−236
@@ -1,236 +0,0 @@
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.TaggedTrans
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− ask = Lift.lift (ask @tag)
81− local = Lift.liftLocal (ask @tag) (local @tag)
82− reader = Lift.lift . reader @tag
83−
84−instance {-# OVERLAPPABLE #-}
85− ( Monad (trans m)
86− , MonadReader tag r (TaggedTrans effs trans m)
87− ) => MonadReader tag r (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
88− where
89−
90− ask =
91− (coerce ::
92− TaggedTrans effs trans m r ->
93− TaggedTrans (eff ': effs) trans m r)
94− (ask @tag)
95−
96− local =
97− (coerce :: forall a .
98− Lift.Local r (TaggedTrans effs trans m) a ->
99− Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
100− (local @tag)
101−
102− reader =
103− (coerce :: forall a .
104− ((r -> a) -> TaggedTrans effs trans m a) ->
105− ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
106− (reader @tag)
107−
108−-- | Retrieves a function of the current environment.
109−asks
110− :: forall tag r m a
111− . MonadReader tag r m
112− => (r -> a)
113− -- ^ The selector function to apply to the environment.
114− -> m a
115−asks = reader @tag
116−
117−-- | Encode type-level information for 'ReaderT'.
118−data READER
119−
120−-- | The parameterizable reader monad.
121−--
122−-- Computations are functions of a shared environment.
123−--
124−-- The 'return' function ignores the environment, while '>>=' passes
125−-- the inherited environment to both subcomputations.
126−type Reader tag r = ReaderT tag r Identity
127−
128−-- | The reader monad transformer,
129−-- which adds a read-only environment to the given monad.
130−--
131−-- The 'return' function ignores the environment, while '>>=' passes
132−-- the inherited environment to both subcomputations.
133−type ReaderT tag r = TaggedTrans (TAGGED READER tag) (T.ReaderT r)
134−
135−-- | Constructor for computations in the reader monad transformer.
136−readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
137−readerT = coerce (T.ReaderT @r @m @a)
138−
139−-- | Runs a 'ReaderT' with the given environment
140−-- and returns the final value.
141−runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
142−runReaderT = coerce (T.runReaderT @r @m @a)
143−
144−-- | Runs a 'ReaderT' with the given environment
145−-- and returns the final value.
146−runReader :: forall tag r a . Reader tag r a -> r -> a
147−runReader = coerce (T.runReader @r @a)
148−
149−type instance HandleSuper READER r trans = ()
150−type instance HandleConstraint READER r trans m =
151− T.MonadReader r (trans m)
152−
153−instance Handle READER r (T.ReaderT r) where
154− handling r = r
155−
156−instance
157− ( Handle READER r trans
158− , Monad m, Monad (trans m)
159− ) => MonadReader tag r (TaggedTrans (TAGGED READER tag) trans m)
160− where
161−
162− ask =
163− handling @READER @r @trans @m $
164− coerce (T.ask @r @(trans m))
165−
166− local =
167− handling @READER @r @trans @m $
168− coerce (T.local @r @(trans m) @a) ::
169− forall eff a . Local r (TaggedTrans eff trans m) a
170−
171− reader =
172− handling @READER @r @trans @m $
173− coerce (T.reader @r @(trans m) @a) ::
174− forall eff a . (r -> a) -> TaggedTrans eff trans m a
175−
176−instance
177− ( HasLens tag payload r
178− , Handle READER payload trans
179− , Monad m, Monad (trans m)
180− ) => MonadReader tag r (TaggedTrans (TAGGED READER tag ': effs) trans m)
181− where
182−
183− ask =
184− handling @READER @payload @trans @m $
185− (coerce :: forall eff a .
186− trans m a ->
187− TaggedTrans eff trans m a)
188− (T.asks (view (lensOf @tag @payload @r)))
189−
190− local f =
191− handling @READER @payload @trans @m $
192− (coerce :: forall eff a .
193− (trans m a -> trans m a) ->
194− (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
195− (T.local (over (lensOf @tag @payload @r) f))
196−
197−type family READERS (ts :: HList xs) :: [Type] where
198− READERS 'HNil = '[]
199− READERS ('HCons t ts) = TAGGED READER t ': READERS ts
200−
201−type ReadersT r = TaggedTrans (READERS (Tags r)) (T.ReaderT r)
202−
203−type Readers r = ReadersT r Identity
204−
205−runReadersT :: forall p m a . ReadersT p m a -> p -> m a
206−runReadersT = coerce (T.runReaderT @p @m @a)
207−
208−runReaders :: forall p a . Readers p a -> p -> a
209−runReaders = coerce (T.runReader @p @a)
210−
211−type ReaderT' r = ReaderT r r
212−
213−readerT' :: (r -> m a) -> ReaderT' r m a
214−readerT' = readerT
215−
216−runReaderT' :: ReaderT' r m a -> r -> m a
217−runReaderT' = runReaderT
218−
219−type Reader' r = Reader r r
220−
221−runReader' :: Reader' r a -> r -> a
222−runReader' = runReader
223−
224−type MonadReader' r = MonadReader r r
225−
226−local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
227−local' = local @r
228−
229−ask' :: forall r m . MonadReader' r m => m r
230−ask' = ask @r
231−
232−reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
233−reader' = reader @r
234−
235−asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
236−asks' = asks @r
src/Ether/State.hsdeleted−415
@@ -1,415 +0,0 @@
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.Internal
89−import Ether.TaggedTrans
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− get = Lift.lift (get @tag)
118− put = Lift.lift . put @tag
119− state = Lift.lift . state @tag
120−
121−instance {-# OVERLAPPABLE #-}
122− ( Monad (trans m)
123− , MonadState tag s (TaggedTrans effs trans m)
124− ) => MonadState tag s (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
125− where
126−
127− get =
128− (coerce ::
129− TaggedTrans effs trans m s ->
130− TaggedTrans (eff ': effs) trans m s)
131− (get @tag)
132−
133− put =
134− (coerce ::
135− (s -> TaggedTrans effs trans m ()) ->
136− (s -> TaggedTrans (eff ': effs) trans m ()))
137− (put @tag)
138−
139− state =
140− (coerce :: forall a .
141− ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
142− ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
143− (state @tag)
144−
145−-- | Modifies the state inside a state monad.
146−modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
147−modify f = state @tag (\s -> ((), f s))
148−
149−-- | Gets specific component of the state, using a projection function supplied.
150−gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
151−gets f = fmap f (get @tag)
152−
153−-- | Encode type-level information for 'StateT'.
154−data STATE
155−
156−type instance HandleSuper STATE s trans = ()
157−type instance HandleConstraint STATE s trans m =
158− T.MonadState s (trans m)
159−
160−instance Handle STATE s (T.Strict.StateT s) where
161− handling r = r
162−
163−instance Handle STATE s (T.Lazy.StateT s) where
164− handling r = r
165−
166−instance
167− ( Handle STATE s trans
168− , Monad m, Monad (trans m)
169− ) => MonadState tag s (TaggedTrans (TAGGED STATE tag) trans m)
170− where
171−
172− get =
173− handling @STATE @s @trans @m $
174− coerce (T.get @s @(trans m))
175−
176− put =
177− handling @STATE @s @trans @m $
178− coerce (T.put @s @(trans m))
179−
180− state =
181− handling @STATE @s @trans @m $
182− coerce (T.state @s @(trans m) @a) ::
183− forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
184−
185−instance
186− ( HasLens tag payload s
187− , Handle STATE payload trans
188− , Monad m, Monad (trans m)
189− ) => MonadState tag s (TaggedTrans (TAGGED STATE tag ': effs) trans m)
190− where
191−
192− get =
193− handling @STATE @payload @trans @m $
194− (coerce :: forall eff a .
195− trans m a ->
196− TaggedTrans eff trans m a)
197− (T.gets (view (lensOf @tag @payload @s)))
198−
199− put s =
200− handling @STATE @payload @trans @m $
201− (coerce :: forall eff a .
202− trans m a ->
203− TaggedTrans eff trans m a)
204− (T.modify (over (lensOf @tag @payload @s) (const s)))
205−
206− state f =
207− handling @STATE @payload @trans @m $
208− (coerce :: forall eff a .
209− trans m a ->
210− TaggedTrans eff trans m a)
211− (T.state (lensOf @tag @payload @s f))
212−
213−-- | The parametrizable state monad.
214−--
215−-- Computations have access to a mutable state.
216−--
217−-- The 'return' function leaves the state unchanged, while '>>=' uses
218−-- the final state of the first computation as the initial state of the second.
219−type State tag r = StateT tag r Identity
220−
221−-- | The state monad transformer.
222−--
223−-- The 'return' function leaves the state unchanged, while '>>=' uses
224−-- the final state of the first computation as the initial state of the second.
225−type StateT tag s = TaggedTrans (TAGGED STATE tag) (T.Strict.StateT s)
226−
227−-- | Constructor for computations in the state monad transformer.
228−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
229−stateT = coerce (T.Strict.StateT @s @m @a)
230−
231−-- | Runs a 'StateT' with the given initial state
232−-- and returns both the final value and the final state.
233−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
234−runStateT = coerce (T.Strict.runStateT @s @m @a)
235−
236−-- | Runs a 'StateT' with the given initial state
237−-- and returns the final value, discarding the final state.
238−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
239−evalStateT = coerce (T.Strict.evalStateT @m @s @a)
240−
241−-- | Runs a 'StateT' with the given initial state
242−-- and returns the final state, discarding the final value.
243−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
244−execStateT = coerce (T.Strict.execStateT @m @s @a)
245−
246−-- | Runs a 'State' with the given initial state
247−-- and returns both the final value and the final state.
248−runState :: forall tag s a . State tag s a -> s -> (a, s)
249−runState = coerce (T.Strict.runState @s @a)
250−
251−-- | Runs a 'State' with the given initial state
252−-- and returns the final value, discarding the final state.
253−evalState :: forall tag s a . State tag s a -> s -> a
254−evalState = coerce (T.Strict.evalState @s @a)
255−
256−-- | Runs a 'State' with the given initial state
257−-- and returns the final state, discarding the final value.
258−execState :: forall tag s a . State tag s a -> s -> s
259−execState = coerce (T.Strict.execState @s @a)
260−
261−-- | The parametrizable state monad.
262−--
263−-- Computations have access to a mutable state.
264−--
265−-- The 'return' function leaves the state unchanged, while '>>=' uses
266−-- the final state of the first computation as the initial state of the second.
267−type LazyState tag r = LazyStateT tag r Identity
268−
269−-- | The state monad transformer.
270−--
271−-- The 'return' function leaves the state unchanged, while '>>=' uses
272−-- the final state of the first computation as the initial state of the second.
273−type LazyStateT tag s = TaggedTrans (TAGGED STATE tag) (T.Lazy.StateT s)
274−
275−-- | Constructor for computations in the state monad transformer.
276−lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
277−lazyStateT = coerce (T.Lazy.StateT @s @m @a)
278−
279−-- | Runs a 'StateT' with the given initial state
280−-- and returns both the final value and the final state.
281−runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
282−runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
283−
284−-- | Runs a 'StateT' with the given initial state
285−-- and returns the final value, discarding the final state.
286−evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
287−evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
288−
289−-- | Runs a 'StateT' with the given initial state
290−-- and returns the final state, discarding the final value.
291−execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
292−execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
293−
294−-- | Runs a 'State' with the given initial state
295−-- and returns both the final value and the final state.
296−runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
297−runLazyState = coerce (T.Lazy.runState @s @a)
298−
299−-- | Runs a 'State' with the given initial state
300−-- and returns the final value, discarding the final state.
301−evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
302−evalLazyState = coerce (T.Lazy.evalState @s @a)
303−
304−-- | Runs a 'State' with the given initial state
305−-- and returns the final state, discarding the final value.
306−execLazyState :: forall tag s a . LazyState tag s a -> s -> s
307−execLazyState = coerce (T.Lazy.execState @s @a)
308−
309−type family STATES (ts :: HList xs) :: [Type] where
310− STATES 'HNil = '[]
311− STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
312−
313−type StatesT s = TaggedTrans (STATES (Tags s)) (T.Strict.StateT s)
314−
315−type States s = StatesT s Identity
316−
317−runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
318−runStatesT = coerce (T.Strict.runStateT @p @m @a)
319−
320−runStates :: forall p a . States p a -> p -> (a, p)
321−runStates = coerce (T.Strict.runState @p @a)
322−
323−type StateT' s = StateT s s
324−
325−stateT' :: (s -> m (a, s)) -> StateT' s m a
326−stateT' = stateT
327−
328−runStateT' :: StateT' s m a -> s -> m (a, s)
329−runStateT' = runStateT
330−
331−runState' :: State' s a -> s -> (a, s)
332−runState' = runState
333−
334−evalStateT' :: Monad m => StateT' s m a -> s -> m a
335−evalStateT' = evalStateT
336−
337−type State' s = State s s
338−
339−evalState' :: State' s a -> s -> a
340−evalState' = evalState
341−
342−execStateT' :: Monad m => StateT' s m a -> s -> m s
343−execStateT' = execStateT
344−
345−execState' :: State' s a -> s -> s
346−execState' = execState
347−
348−type LazyStateT' s = LazyStateT s s
349−
350−lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
351−lazyStateT' = lazyStateT
352−
353−runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
354−runLazyStateT' = runLazyStateT
355−
356−runLazyState' :: LazyState' s a -> s -> (a, s)
357−runLazyState' = runLazyState
358−
359−evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
360−evalLazyStateT' = evalLazyStateT
361−
362−type LazyState' s = LazyState s s
363−
364−evalLazyState' :: LazyState' s a -> s -> a
365−evalLazyState' = evalLazyState
366−
367−execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
368−execLazyStateT' = execLazyStateT
369−
370−execLazyState' :: LazyState' s a -> s -> s
371−execLazyState' = execLazyState
372−
373−type MonadState' s = MonadState s s
374−
375−get' :: forall s m . MonadState' s m => m s
376−get' = get @s
377−
378−gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
379−gets' = gets @s
380−
381−put' :: forall s m . MonadState' s m => s -> m ()
382−put' = put @s
383−
384−state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
385−state' = state @s
386−
387−modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
388−modify' = modify @s
389−
390−-- | Encode type-level information for 'zoom'.
391−data ZOOM t z
392−
393−type ZoomT t (z :: Type) = TaggedTrans (ZOOM t z) IdentityT
394−
395−-- | Zoom into a part of a state using a lens.
396−zoom
397− :: forall tag sOuter sInner m a
398− . Lens' sOuter sInner
399− -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
400− -> m a
401−zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
402−
403−instance
404− ( MonadState tag sOuter m
405− , Reifies z (ReifiedLens' sOuter sInner)
406− , trans ~ IdentityT
407− ) => MonadState tag sInner (TaggedTrans (ZOOM tag z) trans m)
408− where
409− state =
410− (coerce :: forall eff r a .
411− (r -> m a) ->
412− (r -> TaggedTrans eff trans m a))
413− (state @tag . l)
414− where
415− Lens l = reflect (Proxy :: Proxy z)
src/Ether/TagDispatch.hsdeleted−138
@@ -1,138 +0,0 @@
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.TaggedTrans
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 = TaggedTrans (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−
67−instance {-# OVERLAPPING #-}
68− ( MonadReader tag r m, trans ~ IdentityT
69− ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
70− where
71− ask = ask @tag
72− local = local @tag
73− reader = reader @tag
74−
75−instance {-# OVERLAPPING #-}
76− ( MonadState tag s m, trans ~ IdentityT
77− ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
78− where
79− get = get @tag
80− put = put @tag
81− state = state @tag
82−
83−instance {-# OVERLAPPING #-}
84− ( MonadExcept tag e m, trans ~ IdentityT
85− ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
86− where
87− throwError = throw @tag
88− catchError = catch @tag
89−
90−instance {-# OVERLAPPING #-}
91− ( MonadWriter tag w m, trans ~ IdentityT
92− ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
93− where
94− writer = writer @tag
95− tell = tell @tag
96− listen = listen @tag
97− pass = pass @tag
98−
99−-- | Encode type-level information for 'tagReplace'.
100−data TAG_REPLACE tOld tNew
101−
102−type TagReplaceT tOld tNew = TaggedTrans (TAG_REPLACE tOld tNew) IdentityT
103−
104−-- | Replace a tag with another tag.
105−tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
106−tagReplace = coerce (runIdentityT @_ @m @a)
107−
108−instance
109− ( MonadReader tNew r m, trans ~ IdentityT
110− ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
111− where
112− ask = ask @tNew
113− local = local @tNew
114− reader = reader @tNew
115−
116−instance
117− ( MonadState tNew s m, trans ~ IdentityT
118− ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
119− where
120− get = get @tNew
121− put = put @tNew
122− state = state @tNew
123−
124−instance
125− ( MonadExcept tNew e m, trans ~ IdentityT
126− ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
127− where
128− throw = throw @tNew
129− catch = catch @tNew
130−
131−instance
132− ( MonadWriter tNew w m, trans ~ IdentityT
133− ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
134− where
135− writer = writer @tNew
136− tell = tell @tNew
137− listen = listen @tNew
138− pass = pass @tNew
src/Ether/TaggedTrans.hsdeleted−206
@@ -1,206 +0,0 @@
1−-- The use of ImpredicativeTypes here is safe, see discussion under GitHub issue
2−-- #35. It's only needed to allow the visible type application of a polytype.
3−{-# LANGUAGE ImpredicativeTypes #-}
4−
5−module Ether.TaggedTrans
6− ( TaggedTrans(..)
7− ) where
8−
9−import Control.Applicative
10−import Control.Monad (MonadPlus)
11−import Control.Monad.Fix (MonadFix)
12−import Control.Monad.Trans.Class (MonadTrans, lift)
13−import Control.Monad.IO.Class (MonadIO)
14−import Control.Monad.Morph (MFunctor(..), MMonad(..))
15−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
16−
17−import qualified Control.Monad.Base as MB
18−import qualified Control.Monad.Trans.Control as MC
19−
20−import qualified Control.Monad.Trans.Lift.StT as Lift
21−import qualified Control.Monad.Trans.Lift.Local as Lift
22−import qualified Control.Monad.Trans.Lift.Catch as Lift
23−import qualified Control.Monad.Trans.Lift.Listen as Lift
24−import qualified Control.Monad.Trans.Lift.Pass as Lift
25−import qualified Control.Monad.Trans.Lift.CallCC as Lift
26−
27−import qualified Control.Monad.Cont.Class as Mtl
28−import qualified Control.Monad.Reader.Class as Mtl
29−import qualified Control.Monad.State.Class as Mtl
30−import qualified Control.Monad.Writer.Class as Mtl
31−import qualified Control.Monad.Error.Class as Mtl
32−
33−import GHC.Generics (Generic)
34−import Data.Coerce (coerce)
35−
36−newtype TaggedTrans tag trans m a = TaggedTrans (trans m a)
37− deriving
38− ( Generic
39− , Functor, Applicative, Alternative, Monad, MonadPlus
40− , MonadFix, MonadTrans, MonadIO
41− , MonadThrow, MonadCatch, MonadMask )
42−
43−type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
44−
45−type Unpack tag trans m a = TaggedTrans tag trans m a -> trans m a
46−
47−instance
48− ( MB.MonadBase b (trans m)
49− ) => MB.MonadBase b (TaggedTrans tag trans m)
50− where
51− liftBase =
52− (coerce :: forall a .
53− (b a -> trans m a) ->
54− (b a -> TaggedTrans tag trans m a))
55− MB.liftBase
56−
57−instance
58− ( MC.MonadTransControl trans
59− ) => MC.MonadTransControl (TaggedTrans tag trans)
60− where
61− type StT (TaggedTrans tag trans) a = MC.StT trans a
62−
63− liftWith = MC.defaultLiftWith
64− (coerce :: Pack tag trans m a)
65− (coerce :: Unpack tag trans m a)
66−
67− restoreT = MC.defaultRestoreT
68− (coerce :: Pack tag trans m a)
69−
70−type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
71−
72−newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
73−
74−coerceLiftBaseWith ::
75− LiftBaseWith b (trans m) a ->
76− LiftBaseWith b (TaggedTrans tag trans m) a
77−coerceLiftBaseWith lbw =
78− unLBW (coerce (LBW lbw))
79−
80−instance
81− ( MC.MonadBaseControl b (trans m)
82− ) => MC.MonadBaseControl b (TaggedTrans tag trans m)
83− where
84− type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
85−
86− liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
87−
88− restoreM =
89− (coerce :: forall a .
90− (MC.StM (trans m) a -> trans m a) ->
91− (MC.StM (trans m) a -> TaggedTrans tag trans m a))
92− MC.restoreM
93−
94−type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
95−
96−instance Lift.LiftLocal trans => Lift.LiftLocal (TaggedTrans tag trans) where
97− liftLocal =
98− Lift.defaultLiftLocal
99− (coerce :: Pack tag trans m a)
100− (coerce :: Unpack tag trans m a)
101−
102−instance Lift.LiftCatch trans => Lift.LiftCatch (TaggedTrans tag trans) where
103− liftCatch =
104− Lift.defaultLiftCatch
105− (coerce :: Pack tag trans m a)
106− (coerce :: Unpack tag trans m a)
107−
108−instance Lift.LiftListen trans => Lift.LiftListen (TaggedTrans tag trans) where
109− liftListen =
110− Lift.defaultLiftListen
111− (coerce :: Pack tag trans m a)
112− (coerce :: Unpack tag trans m a)
113−
114−instance Lift.LiftPass trans => Lift.LiftPass (TaggedTrans tag trans) where
115− liftPass =
116− Lift.defaultLiftPass
117− (coerce :: Pack tag trans m a)
118− (coerce :: Unpack tag trans m a)
119−
120−instance Lift.LiftCallCC trans => Lift.LiftCallCC (TaggedTrans tag trans) where
121− liftCallCC =
122− Lift.defaultLiftCallCC
123− (coerce :: Pack tag trans m a)
124− (coerce :: Unpack tag trans m a)
125− liftCallCC' =
126− Lift.defaultLiftCallCC'
127− (coerce :: Pack tag trans m a)
128− (coerce :: Unpack tag trans m a)
129−
130−
131−-- Instances for mtl classes
132−
133−instance
134− ( Mtl.MonadCont m
135− , Lift.LiftCallCC trans
136− , Monad (trans m)
137− ) => Mtl.MonadCont (TaggedTrans tag trans m)
138− where
139− callCC = Lift.liftCallCC' Mtl.callCC
140−
141−instance
142− ( Mtl.MonadReader r m
143− , Lift.LiftLocal trans
144− , Monad (trans m)
145− ) => Mtl.MonadReader r (TaggedTrans tag trans m)
146− where
147− ask = lift Mtl.ask
148− local = Lift.liftLocal Mtl.ask Mtl.local
149− reader = lift . Mtl.reader
150−
151−instance
152− ( Mtl.MonadState s m
153− , MonadTrans trans
154− , Monad (trans m)
155− ) => Mtl.MonadState s (TaggedTrans tag trans m)
156− where
157− get = lift Mtl.get
158− put = lift . Mtl.put
159− state = lift . Mtl.state
160−
161−instance
162− ( Mtl.MonadWriter w m
163− , Lift.LiftListen trans
164− , Lift.LiftPass trans
165− , Monad (trans m)
166− ) => Mtl.MonadWriter w (TaggedTrans tag trans m)
167− where
168− writer = lift . Mtl.writer
169− tell = lift . Mtl.tell
170− listen = Lift.liftListen Mtl.listen
171− pass = Lift.liftPass Mtl.pass
172−
173−instance
174− ( Mtl.MonadError e m
175− , Lift.LiftCatch trans
176− , Monad (trans m)
177− ) => Mtl.MonadError e (TaggedTrans tag trans m)
178− where
179− throwError = lift . Mtl.throwError
180− catchError = Lift.liftCatch Mtl.catchError
181−
182−type Hoist trans =
183− forall m n b . Monad m =>
184− (forall a . m a -> n a) -> trans m b -> trans n b
185−
186−-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
187−-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
188−instance MFunctor trans => MFunctor (TaggedTrans tag trans) where
189− hoist =
190− coerce
191− @(Hoist trans)
192− @(Hoist (TaggedTrans tag trans))
193− hoist
194−
195−type Embed trans =
196− forall n m b . Monad n =>
197− (forall a . m a -> trans n a) -> trans m b -> trans n b
198−
199−-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
200−-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
201−instance MMonad trans => MMonad (TaggedTrans tag trans) where
202− embed =
203− coerce
204− @(Embed trans)
205− @(Embed (TaggedTrans tag trans))
206− embed
src/Ether/Writer.hsdeleted−287
@@ -1,287 +0,0 @@
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− -- * The Writer monad (lazy)
21− , LazyWriter
22− , runLazyWriter
23− , execLazyWriter
24− -- * The WriterT monad transformer (lazy)
25− , LazyWriterT
26− , lazyWriterT
27− , runLazyWriterT
28− , execLazyWriterT
29− -- * MonadWriter class (implicit)
30− , MonadWriter'
31− , writer'
32− , tell'
33− , listen'
34− , pass'
35− , listens'
36− , censor'
37− -- * The Writer monad (implicit)
38− , Writer'
39− , runWriter'
40− , execWriter'
41− -- * The WriterT monad transformer (implicit)
42− , WriterT'
43− , writerT'
44− , runWriterT'
45− , execWriterT'
46− -- * The Writer monad (lazy, implicit)
47− , LazyWriter'
48− , runLazyWriter'
49− , execLazyWriter'
50− -- * The WriterT monad transformer (lazy, implicit)
51− , LazyWriterT'
52− , lazyWriterT'
53− , runLazyWriterT'
54− , execLazyWriterT'
55− -- * Internal labels
56− , TAGGED
57− , WRITER
58− ) where
59−
60−import Control.Monad.Signatures (Listen, Pass)
61−import qualified Control.Monad.Trans.Lift.Listen as Lift
62−import qualified Control.Monad.Trans.Lift.Pass as Lift
63−import qualified Control.Monad.Writer.Class as T
64−import qualified Control.Monad.Writer.CPS as T.CPS
65−import qualified Control.Monad.Writer.Lazy as T.Lazy
66−import Data.Coerce
67−import Data.Functor.Identity
68−
69−import Ether.Internal
70−import Ether.TaggedTrans
71−
72−class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
73−
74− {-# MINIMAL (writer | tell), listen, pass #-}
75−
76− -- | Embed a simple writer action.
77− writer :: (a, w) -> m a
78− writer ~(a, w) = a <$ tell @tag w
79−
80− -- | Append a value to the accumulator within the monad.
81− tell :: w -> m ()
82− tell w = writer @tag ((),w)
83−
84− -- | Execute an action and add its accumulator
85− -- to the value of the computation.
86− listen :: m a -> m (a, w)
87−
88− -- | Execute an action which returns a value and a function,
89− -- and return the value, applying the function to the accumulator.
90− pass :: m (a, w -> w) -> m a
91−
92−instance {-# OVERLAPPABLE #-}
93− ( Lift.LiftListen t
94− , Lift.LiftPass t
95− , Monad (t m)
96− , MonadWriter tag w m
97− , Monoid w
98− ) => MonadWriter tag w (t m) where
99− writer = Lift.lift . writer @tag
100− tell = Lift.lift . tell @tag
101− listen = Lift.liftListen (listen @tag)
102− pass = Lift.liftPass (pass @tag)
103−
104−-- | Execute an action and add the result of applying the given function to
105−-- its accumulator to the value of the computation.
106−listens :: forall tag w m a b . MonadWriter tag w m => (w -> b) -> m a -> m (a, b)
107−listens f m = do
108− ~(a, w) <- listen @tag m
109− return (a, f w)
110−
111−-- | Execute an action and apply a function to its accumulator.
112−censor :: forall tag w m a . MonadWriter tag w m => (w -> w) -> m a -> m a
113−censor f m = pass @tag $ do
114− a <- m
115− return (a, f)
116−
117−-- | Encode type-level information for 'WriterT'.
118−data WRITER
119−
120−type instance HandleSuper WRITER w trans = Monoid w
121−type instance HandleConstraint WRITER w trans m =
122− T.MonadWriter w (trans m)
123−
124−instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
125− handling r = r
126−
127−instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
128− handling r = r
129−
130−instance
131− ( Handle WRITER w trans
132− , Monad m, Monad (trans m)
133− ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
134− where
135−
136− writer =
137− handling @WRITER @w @trans @m $
138− coerce (T.writer @w @(trans m) @a) ::
139− forall eff a . (a, w) -> TaggedTrans eff trans m a
140−
141− tell =
142− handling @WRITER @w @trans @m $
143− coerce (T.tell @w @(trans m))
144−
145− listen =
146− handling @WRITER @w @trans @m $
147− coerce (T.listen @w @(trans m) @a) ::
148− forall eff a . Listen w (TaggedTrans eff trans m) a
149−
150− pass =
151− handling @WRITER @w @trans @m $
152− coerce (T.pass @w @(trans m) @a) ::
153− forall eff a . Pass w (TaggedTrans eff trans m) a
154−
155−-- | The parametrizable writer monad.
156−--
157−-- Computations can accumulate a monoid value.
158−--
159−-- The 'return' function produces the output 'mempty', while '>>=' combines
160−-- the outputs of the subcomputations using 'mappend'.
161−type Writer tag w = WriterT tag w Identity
162−
163−-- | The writer monad transformer.
164−--
165−-- The 'return' function produces the output 'mempty', while '>>=' combines
166−-- the outputs of the subcomputations using 'mappend'.
167−type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
168−
169−-- | Constructor for computations in the writer monad transformer.
170−writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
171−writerT = coerce (T.CPS.writerT @m @w @a)
172−
173−-- | Runs a 'WriterT' and returns both the normal value
174−-- and the final accumulator.
175−runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
176−runWriterT = coerce (T.CPS.runWriterT @w @m @a)
177−
178−-- | Runs a 'Writer' and returns both the normal value
179−-- and the final accumulator.
180−runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
181−runWriter = coerce (T.CPS.runWriter @w @a)
182−
183−-- | Runs a 'WriterT' and returns the final accumulator,
184−-- discarding the normal value.
185−execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
186−execWriterT = coerce (T.CPS.execWriterT @m @w @a)
187−
188−-- | Runs a 'Writer' and returns the final accumulator,
189−-- discarding the normal value.
190−execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
191−execWriter = coerce (T.CPS.execWriter @w @a)
192−
193−-- | The parametrizable writer monad.
194−--
195−-- Computations can accumulate a monoid value.
196−--
197−-- The 'return' function produces the output 'mempty', while '>>=' combines
198−-- the outputs of the subcomputations using 'mappend'.
199−type LazyWriter tag w = LazyWriterT tag w Identity
200−
201−-- | The writer monad transformer.
202−--
203−-- The 'return' function produces the output 'mempty', while '>>=' combines
204−-- the outputs of the subcomputations using 'mappend'.
205−type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
206−
207−-- | Constructor for computations in the writer monad transformer.
208−lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
209−lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
210−
211−-- | Runs a 'WriterT' and returns both the normal value
212−-- and the final accumulator.
213−runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
214−runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
215−
216−-- | Runs a 'Writer' and returns both the normal value
217−-- and the final accumulator.
218−runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
219−runLazyWriter = coerce (T.Lazy.runWriter @w @a)
220−
221−-- | Runs a 'WriterT' and returns the final accumulator,
222−-- discarding the normal value.
223−execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
224−execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
225−
226−-- | Runs a 'Writer' and returns the final accumulator,
227−-- discarding the normal value.
228−execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
229−execLazyWriter = coerce (T.Lazy.execWriter @w @a)
230−
231−type Writer' w = Writer w w
232−
233−runWriter' :: Monoid w => Writer' w a -> (a, w)
234−runWriter' = runWriter
235−
236−execWriter' :: Monoid w => Writer' w a -> w
237−execWriter' = execWriter
238−
239−type WriterT' w = WriterT w w
240−
241−writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
242−writerT' = writerT
243−
244−runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
245−runWriterT' = runWriterT
246−
247−execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
248−execWriterT' = execWriterT
249−
250−type LazyWriter' w = LazyWriter w w
251−
252−runLazyWriter' :: LazyWriter' w a -> (a, w)
253−runLazyWriter' = runLazyWriter
254−
255−execLazyWriter' :: LazyWriter' w a -> w
256−execLazyWriter' = execLazyWriter
257−
258−type LazyWriterT' w = LazyWriterT w w
259−
260−lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
261−lazyWriterT' = lazyWriterT
262−
263−runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
264−runLazyWriterT' = runLazyWriterT
265−
266−execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
267−execLazyWriterT' = execLazyWriterT
268−
269−type MonadWriter' w = MonadWriter w w
270−
271−writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
272−writer' = writer @w
273−
274−tell' :: forall w m . MonadWriter' w m => w -> m ()
275−tell' = tell @w
276−
277−listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
278−listen' = listen @w
279−
280−pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
281−pass' = pass @w
282−
283−listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
284−listens' = listens @w
285−
286−censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
287−censor' = censor @w
stack.yamlnew file+2
@@ -0,0 +1,2 @@
1+resolver: lts-8.12
2+packages: ['.']
test/Regression/T1.hs+5−16
@@ -1,8 +1,7 @@
11module Regression.T1 (test1) where
22
3−import Ether
4−import TupleInstances ()
5−import Data.List (group)
3+import Control.Monad.Ether
4+import Control.Ether.Abbr
65
76import Test.Tasty
87import Test.Tasty.QuickCheck
@@ -11,7 +10,7 @@ data Tag1
1110data Tag2
1211
1312testEther
14− :: (MonadReader Tag1 String m, MonadReader Tag2 String m)
13+ :: Ether '[Tag1 --> String, Tag2 --> String] m
1514 => m ((String, String), (String, String))
1615testEther = do
1716 s1 <- ask @Tag1
@@ -25,10 +24,6 @@ testEther = do
2524
2625runner1 s1 s2 = flip (runReader @Tag1) s1 . flip (runReaderT @Tag2) s2
2726runner2 s1 s2 = flip (runReader @Tag2) s2 . flip (runReaderT @Tag1) s1
28−runner3 s1 s2 = flip runReaders (Tagged @Tag1 s1, Tagged @Tag2 s2)
29−
30−same :: Eq a => [a] -> Bool
31−same = (<=1) . length . group
3227
3328test1 :: TestTree
3429test1 = testGroup "T1: Reader local environment"
@@ -38,13 +33,7 @@ test1 = testGroup "T1: Reader local environment"
3833 , testProperty "runner₂ works"
3934 $ \s1 s2 -> property
4035 $ runner2 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
41− , testProperty "runner₃ works"
42− $ \s1 s2 -> property
43− $ runner3 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
44− , testProperty "runner₁ == runner₂ == runner₃"
36+ , testProperty "runner₁ == runner₂"
4537 $ \s1 s2 -> property
46− $ same
47− [ runner1 s1 s2 testEther
48− , runner2 s1 s2 testEther
49− , runner3 s1 s2 testEther ]
38+ $ runner1 s1 s2 testEther == runner2 s1 s2 testEther
5039 ]
test/Regression/T10.hs+10−11
@@ -2,23 +2,22 @@ module Regression.T10 (test10) where
22
33import Control.Applicative
44import Data.Functor.Identity
5−
6−import Ether
5+import qualified Control.Monad.Ether.Implicit as I
76
87import Test.Tasty
98import Test.Tasty.QuickCheck
109
11−testEther :: Integer -> StateT' Integer Maybe [Integer]
10+testEther :: Integer -> I.StateT Integer Maybe [Integer]
1211testEther m = range
1312 where
1413 range = liftA2 (:) yield (range <|> pure [])
15− yield = stateT' $ \n -> do
16− guard (n <= m)
14+ yield = I.stateT $ \n -> do
15+ I.guard (n <= m)
1716 Just (n, n + 1)
1817
19−testEther' :: Integer -> State' Integer [Integer]
18+testEther' :: Integer -> I.State Integer [Integer]
2019testEther' m =
21− stateT' $ Identity . maybe ([], m + 1) id . runStateT' (testEther m)
20+ I.stateT $ Identity . maybe ([], m + 1) id . I.runStateT (testEther m)
2221
2322next1 :: Integer -> Integer -> Maybe Integer
2423next1 m n
@@ -33,11 +32,11 @@ range1 m n
3332test10 :: TestTree
3433test10 = testGroup "T10: Alternative instance"
3534 [ testProperty "execStateT works"
36− $ \m n -> execStateT' (testEther m) n == next1 m n
35+ $ \m n -> I.execStateT (testEther m) n == next1 m n
3736 , testProperty "evalStateT works"
38− $ \m n -> evalStateT' (testEther m) n == range1 m n
37+ $ \m n -> I.evalStateT (testEther m) n == range1 m n
3938 , testProperty "execState works"
40− $ \m n -> execState' (testEther' m) n == m + 1
39+ $ \m n -> I.execState (testEther' m) n == m + 1
4140 , testProperty "evalState works"
42− $ \m n -> evalState' (testEther' m) n == [n..m]
41+ $ \m n -> I.evalState (testEther' m) n == [n..m]
4342 ]
test/Regression/T11.hs+4−4
@@ -1,8 +1,8 @@
11module Regression.T11 (test11) where
22
3−import Ether
4−
53import Data.Bool
4+import Control.Monad.Ether
5+
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 (execLazyStateT @STag) []
31+ . flip (execStateT @STag) []
3232 . flip T.evalStateT False
3333
3434runner2 n
3535 = flip T.evalState False
36− . flip (execLazyStateT @STag) []
36+ . flip (execStateT @STag) []
3737 . flip T.runReaderT n
3838
3939test11 :: TestTree
test/Regression/T12.hs+4−3
@@ -1,6 +1,7 @@
11module Regression.T12 (test12) where
22
3−import Ether
3+import Control.Monad.Ether.State
4+import Control.Monad.Ether.State.Zoom
45import Control.Lens
56
67import Test.Tasty
@@ -13,8 +14,8 @@ succState = modify @Foo succ
1314
1415testEther :: (Enum a, MonadState Foo (a, a) m) => m (a, a)
1516testEther = do
16− Ether.zoom @Foo _1 succState
17− Ether.zoom @Foo _2 $ modify @Foo pred
17+ tagZoom @Foo _1 succState
18+ tagZoom @Foo _2 $ modify @Foo pred
1819 get @Foo
1920
2021model :: Enum a => (a, a) -> (a, a)
test/Regression/T2.hs+9−7
@@ -1,18 +1,20 @@
11module Regression.T2 (test2) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import qualified Control.Monad.Ether.Implicit as I
5+import qualified Control.Ether.Implicit.Abbr as I
46
57import Test.Tasty
68import Test.Tasty.QuickCheck
79
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'
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
1214 return (if b then "" else show n)
1315
14−runner1 (n :: Integer) = flip runReader' n . flip runReaderT' True
15−runner2 (n :: Integer) = flip runReader' True . flip runReaderT' n
16+runner1 (n :: Integer) = flip I.runReader n . flip I.runReaderT True
17+runner2 (n :: Integer) = flip I.runReader True . flip I.runReaderT n
1618
1719test2 :: TestTree
1820test2 = testGroup "T2: Implicit tags"
test/Regression/T3.hs+3−2
@@ -1,6 +1,7 @@
11module Regression.T3 (test3) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import qualified Control.Monad.Reader as T
67import qualified Control.Monad.State as T
@@ -19,7 +20,7 @@ testMTL = do
1920 return (a * b)
2021
2122testEther
22− :: (MonadReader STag Int m, MonadState STag Int m, MonadReader RTag Int m)
23+ :: Ether '[STag --> Int, STag <-> Int, RTag --> Int] m
2324 => m (Int, Int, Int)
2425testEther = local @RTag (*2) $ do
2526 a_mul_b <- tagAttach @STag testMTL
test/Regression/T4.hs+3−2
@@ -1,13 +1,14 @@
11module Regression.T4 (test4) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import Test.Tasty
67import Test.Tasty.QuickCheck
78
89data RTag
910
10−testEther :: MonadReader RTag Int m => m Int
11+testEther :: Ether '[RTag --> Int] m => m Int
1112testEther = ask @RTag
1213
1314runner r
test/Regression/T5.hs+11−8
@@ -1,6 +1,9 @@
11module Regression.T5 (test5) where
22
3−import Ether
3+import Control.Ether.Abbr
4+
5+import qualified Control.Monad.Ether.Implicit as I
6+import qualified Control.Ether.Implicit.Abbr as I
47
58import Test.Tasty
69import Test.Tasty.QuickCheck
@@ -13,22 +16,22 @@ incCounter = succ
1316
1417testEther
1518 :: (Num a, Ord a)
16− => (MonadReader' a m, MonadState' Counter m)
19+ => Ether '[I.R a, I.S Counter] m
1720 => m a
1821testEther = do
19− a <- ask'
22+ a <- I.ask
2023 if a <= 0
2124 then do
22− put' (0 :: Counter)
25+ I.put (0 :: Counter)
2326 return 1
2427 else do
25− modify' incCounter -- overriden in the base case
26− b <- runReaderT' testEther (a - 1)
27− modify' incCounter
28+ I.modify incCounter -- overriden in the base case
29+ b <- I.runReaderT testEther (a - 1)
30+ I.modify incCounter
2831 return (a * b)
2932
3033runner :: (Num a, Ord a) => a -> (a, Counter)
31−runner a = runState' (runReaderT' testEther a) (0 :: Counter)
34+runner a = I.runState (I.runReaderT testEther a) (0 :: Counter)
3235
3336factorial :: (Num a, Enum a) => a -> a
3437factorial a = product [1..a]
test/Regression/T6.hs+16−14
@@ -1,7 +1,10 @@
11module Regression.T6 (test6) where
22
3−import Data.Function
4−import Ether
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
58
69import Test.Tasty
710import Test.Tasty.QuickCheck
@@ -14,33 +17,32 @@ data NegativeLog a = NegativeLog a
1417
1518testEther
1619 :: (Floating a, Ord a)
17− => (MonadExcept' DivideByZero m, MonadExcept' (NegativeLog a) m)
20+ => Ether '[I.E DivideByZero, I.E (NegativeLog a)] m
1821 => a -> a -> m a
1922testEther a b = do
20− when (b == 0) (throw' DivideByZero)
23+ when (b == 0) (I.throw DivideByZero)
2124 let d = a / b
22− when (d < 0) (throw' (NegativeLog d))
25+ when (d < 0) (I.throw (NegativeLog d))
2326 return (log d)
2427
28+-- Copied verbatim from "Data.Function" to support @base < 4.8@.
29+(&) :: a -> (a -> b) -> b
30+x & f = f x
31+
2532handleNegativeLog (NegativeLog (x :: Double)) = "nl: " ++ show x
2633handleDivideByZero DivideByZero = "dz"
2734
28−handleT' :: Functor m => (e -> a) -> ExceptT' e m a -> m a
29−handleT' h m = fmap (either h id) (runExceptT' m)
30−
3135runner1 :: Double -> Double -> String
3236runner1 a b = do
3337 (show `fmap` testEther a b)
34− & handleT' handleNegativeLog
35− & handleT' handleDivideByZero
36− & runIdentity
38+ & I.handleT handleNegativeLog
39+ & I.handle handleDivideByZero
3740
3841runner2 :: Double -> Double -> String
3942runner2 a b = do
4043 (show `fmap` testEther a b)
41− & handleT' handleDivideByZero
42− & handleT' handleNegativeLog
43− & runIdentity
44+ & I.handleT handleDivideByZero
45+ & I.handle handleNegativeLog
4446
4547logDiv :: Double -> Double -> String
4648logDiv 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 Ether
6+import Control.Monad.Ether
77import qualified Control.Monad.Writer as T
88
99import Test.Tasty
test/Regression/T8.hs+3−2
@@ -1,6 +1,7 @@
11module Regression.T8 (test8) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import qualified Control.Monad.State as T
67
@@ -17,7 +18,7 @@ testMTL2 :: T.MonadState Bool m => m ()
1718testMTL2 = T.modify not
1819
1920testEther
20− :: (MonadState Foo Int m, MonadState Bar Bool m)
21+ :: Ether '[Foo <-> Int, Bar <-> Bool] m
2122 => m String
2223testEther = do
2324 tagAttach @Foo testMTL1
test/Regression/T9.hs+5−4
@@ -1,6 +1,7 @@
11module Regression.T9 (test9) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import Test.Tasty
67import Test.Tasty.QuickCheck
@@ -8,16 +9,16 @@ import Test.Tasty.QuickCheck
89data Foo
910data Bar
1011
11−testEther1 :: MonadState Foo Int m => m String
12+testEther1 :: Ether '[Foo <-> Int] m => m String
1213testEther1 = do
1314 modify @Foo negate
1415 gets @Foo show
1516
16−testEther2 :: MonadState Bar Int m => m String
17+testEther2 :: Ether '[Bar <-> Int] m => m String
1718testEther2 = tagReplace @Foo @Bar testEther1
1819
1920testEther
20− :: (MonadState Foo Int m, MonadState Bar Int m)
21+ :: Ether '[Foo <-> Int, Bar <-> Int] m
2122 => m String
2223testEther = do
2324 a <- testEther1
test/TupleInstances.hsdeleted−9
@@ -1,9 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module TupleInstances () where
5−
6−#ifdef DISABLE_TUP_INSTANCES
7−import Ether.Internal (makeTupleInstancesHasLens)
8−makeTupleInstancesHasLens [2]
9−#endif