on master help sign in
71 files changed+2125−2321
since splitsnapshots
unifiedsplit
.gitignore+17−2 .travis.yml+25−18 ether/CHANGELOG.md → CHANGELOG.md+8−1 ether/LICENSE → LICENSE README.md−16 ether-suite/Setup.hs → Setup.hs ether-suite/bench/Bench.hs → bench/Bench.hs+63−66 bench/TupleInstances.hs+9 cabal.project−3 ether-suite/ether-suite.cabal−130 ether.cabal+237 ether/Setup.hs−2 ether/ether.cabal−107 ether/src/Control/Ether/Abbr.hs−61 ether/src/Control/Ether/Implicit/Abbr.hs−23 ether/src/Control/Ether/Optic.hs−142 ether/src/Control/Monad/Ether.hs−13 ether/src/Control/Monad/Ether/Except.hs−89 ether/src/Control/Monad/Ether/Except/Class.hs−29 ether/src/Control/Monad/Ether/Handle.hs−35 ether/src/Control/Monad/Ether/Implicit.hs−13 ether/src/Control/Monad/Ether/Implicit/Except.hs−58 ether/src/Control/Monad/Ether/Implicit/Reader.hs−57 ether/src/Control/Monad/Ether/Implicit/State.hs−7 ether/src/Control/Monad/Ether/Implicit/State/Lazy.hs−82 ether/src/Control/Monad/Ether/Implicit/State/Strict.hs−82 ether/src/Control/Monad/Ether/Implicit/Writer.hs−77 ether/src/Control/Monad/Ether/Reader.hs−128 ether/src/Control/Monad/Ether/Reader/Class.hs−77 ether/src/Control/Monad/Ether/Reader/Flatten.hs−29 ether/src/Control/Monad/Ether/State.hs−7 ether/src/Control/Monad/Ether/State/Class.hs−74 ether/src/Control/Monad/Ether/State/Common.hs−90 ether/src/Control/Monad/Ether/State/Flatten.hs−29 ether/src/Control/Monad/Ether/State/Lazy.hs−87 ether/src/Control/Monad/Ether/State/Strict.hs−87 ether/src/Control/Monad/Ether/State/Zoom.hs−47 ether/src/Control/Monad/Ether/TagAttach.hs−66 ether/src/Control/Monad/Ether/TagReplace.hs−61 ether/src/Control/Monad/Ether/Writer.hs−121 ether/src/Control/Monad/Ether/Writer/Class.hs−49 ether/src/Control/Monad/Trans/Ether/Handler.hs−177 shell.nix+22 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−5 ether-suite/test/Regression.hs → test/Regression.hs ether-suite/test/Regression/T1.hs → test/Regression/T1.hs+16−5 ether-suite/test/Regression/T10.hs → test/Regression/T10.hs+11−10 ether-suite/test/Regression/T11.hs → test/Regression/T11.hs+4−4 ether-suite/test/Regression/T12.hs → test/Regression/T12.hs+3−4 ether-suite/test/Regression/T2.hs → test/Regression/T2.hs+7−9 ether-suite/test/Regression/T3.hs → test/Regression/T3.hs+2−3 ether-suite/test/Regression/T4.hs → test/Regression/T4.hs+2−3 ether-suite/test/Regression/T5.hs → test/Regression/T5.hs+8−11 ether-suite/test/Regression/T6.hs → test/Regression/T6.hs+14−16 ether-suite/test/Regression/T7.hs → test/Regression/T7.hs+1−1 ether-suite/test/Regression/T8.hs → test/Regression/T8.hs+2−3 ether-suite/test/Regression/T9.hs → test/Regression/T9.hs+4−5 test/TupleInstances.hs+9
.gitignore+17−2
@@ -1,6 +1,21 @@
1−tags
1+# Cabal
22dist
33dist-newstyle
4−.stack-work
54.cabal-sandbox/
65cabal.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+25−18
@@ -1,24 +1,31 @@
1−sudo: false
1+language: nix
22
3−cache:
4− directories:
5− - $HOME/.stack/
3+os:
4+ - linux
5+ - osx
66
7−before_install:
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
7+env:
8+ - HC=ghc822
9+ - HC=ghc844
10+ - HC=ghc861
1311
14−install:
15− - stack install --only-dependencies --no-terminal
12+before_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
1615
1716script:
18− - stack test ether-suite:regression --no-terminal --ghc-options -Werror
19− - stack bench ether-suite:bench --no-terminal --ghc-options -Werror
17+ - ./nix-cabal new-test ether:regression
18+ - ./nix-cabal new-bench ether:bench
19+
20+cache:
21+ directories:
22+ - ~/.cabal
23+ - ~/.ghc
2024
21−addons:
22− apt:
23− packages:
24− - libgmp-dev
25+matrix:
26+ # broken at the moment
27+ exclude:
28+ - os: osx
29+ env: HC=ghc822
30+ - os: osx
31+ env: HC=ghc861
ether/CHANGELOG.md → CHANGELOG.mdrenamed+8−1
@@ -1,13 +1,20 @@
1+0.5.1.0
2+-------
3+
4+* Disable `HasLens` for tuples via cabal flag.
5+
160.5.0.0
27-------
38
49* Support only GHC 8.0 and higher.
510* Use the `TypeApplications` extension to get rid of `Proxy`.
611* Remove `Control.Ether.TH`.
7−* Unify `Dispatch` and `TaggedTrans` as `Handler`.
12+* Remove `Control.Ether.Abbr`.
13+* Unify `Dispatch` and `TaggedTrans`.
814* Better `MonadBase` and `MonadBaseControl` instances.
915* Add flattening for `ReaderT` and `StateT`.
1016* Add zooming for `MonadState`.
17+* Simpler module structure.
1118
12190.4.1.0
1320-------
ether/LICENSE → LICENSErenamed

The content is the same.

README.md−16
@@ -2,24 +2,8 @@
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)
65
76
87Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
98and [transformers](https://hackage.haskell.org/package/transformers) with tagged
109monad 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.
ether-suite/Setup.hs → Setup.hsrenamed

The content is the same.

ether-suite/bench/Bench.hs → bench/Bench.hsrenamed+63−66
@@ -2,16 +2,13 @@
22
33module Main (main) where
44
5−import Criterion.Main
5+import Control.DeepSeq
6+import qualified Control.Lens as L
67import qualified Control.Monad.Reader as M
78import qualified Control.Monad.State as M
8−import qualified Control.Monad.Ether.Reader as E
9−import qualified Control.Monad.Ether.State as E
10−import qualified Control.Monad.Ether.Reader.Flatten as E.F
11−import qualified Control.Monad.Ether.State.Flatten as E.F
12−import qualified Control.Lens as L
13−import Control.Ether.Optic
14−import Control.DeepSeq
9+import Criterion.Main
10+import Ether
11+import TupleInstances ()
1512
1613id' :: a -> a
1714id' = id
@@ -71,80 +68,80 @@ run_stateCombinerMTL_flat_9
7168 M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
7269
7370readerCombinerEther_sep_9
74− :: ( E.MonadReader 1 Int m
75− , E.MonadReader 2 Int m
76− , E.MonadReader 3 Int m
77− , E.MonadReader 4 Int m
78− , E.MonadReader 5 Int m
79− , E.MonadReader 6 Int m
80− , E.MonadReader 7 Int m
81− , E.MonadReader 8 Int m
82− , E.MonadReader 9 Int m )
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 )
8380 => m ()
8481readerCombinerEther_sep_9 = rnf <$> sequenceA
85− [ E.ask @1
86− , E.ask @2
87− , E.ask @3
88− , E.ask @4
89− , E.ask @5
90− , E.ask @6
91− , E.ask @7
92− , E.ask @8
93− , E.ask @9 ]
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 ]
9491{-# NOINLINE readerCombinerEther_sep_9 #-}
9592
9693stateCombinerEther_sep_9
97− :: ( E.MonadState 1 Int m
98− , E.MonadState 2 Int m
99− , E.MonadState 3 Int m
100− , E.MonadState 4 Int m
101− , E.MonadState 5 Int m
102− , E.MonadState 6 Int m
103− , E.MonadState 7 Int m
104− , E.MonadState 8 Int m
105− , E.MonadState 9 Int m )
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 )
106103 => m ()
107104stateCombinerEther_sep_9 = do
108− E.modify @1 id'
109− E.modify @2 id'
110− E.modify @3 id'
111− E.modify @4 id'
112− E.modify @5 id'
113− E.modify @6 id'
114− E.modify @7 id'
115− E.modify @8 id'
116− E.modify @9 id'
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'
117114 rnf <$> sequenceA
118− [ E.get @1
119− , E.get @2
120− , E.get @3
121− , E.get @4
122− , E.get @5
123− , E.get @6
124− , E.get @7
125− , E.get @8
126− , E.get @9 ]
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 ]
127124{-# NOINLINE stateCombinerEther_sep_9 #-}
128125
129126run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
130127run_readerCombinerEther_nested_9
131128 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
132− = flip (E.runReader @9) a1
133− . flip (E.runReaderT @8) a2
134− . flip (E.runReaderT @7) a3
135− . flip (E.runReaderT @6) a4
136− . flip (E.runReaderT @5) a5
137− . flip (E.runReaderT @4) a6
138− . flip (E.runReaderT @3) a7
139− . flip (E.runReaderT @2) a8
140− . flip (E.runReaderT @1) a9
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
141138 $ readerCombinerEther_sep_9
142139
143140run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
144141run_readerCombinerEther_flatten_9
145142 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
146143 =
147− E.F.runReader
144+ runReaders
148145 readerCombinerEther_sep_9
149146 ( Tagged @1 a9,
150147 Tagged @2 a8,
@@ -159,12 +156,12 @@ run_readerCombinerEther_flatten_9
159156run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
160157run_readerCombinerEther_flattenhalf_9
161158 (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
162− flip E.F.runReader
159+ flip runReaders
163160 ( Tagged @1 a9,
164161 Tagged @2 a8,
165162 Tagged @3 a7,
166163 Tagged @4 a6 ) .
167− flip E.F.runReaderT
164+ flip runReadersT
168165 ( Tagged @5 a5,
169166 Tagged @6 a4,
170167 Tagged @7 a3,
@@ -178,7 +175,7 @@ run_stateCombinerEther_flatten_9 ::
178175run_stateCombinerEther_flatten_9
179176 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
180177 =
181− E.F.runState
178+ runStates
182179 stateCombinerEther_sep_9
183180 ( Tagged @1 a9,
184181 Tagged @2 a8,
bench/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
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
cabal.projectdeleted−3
@@ -1,3 +0,0 @@
1−packages:
2− ether/
3− ether-suite/
ether-suite/ether-suite.cabaldeleted−130
@@ -1,130 +0,0 @@
1−name: ether-suite
2−version: 0.1.0.0
3−build-type: Simple
4−cabal-version: >=1.18
5−
6−library
7− -- Dummy section.
8− default-language: Haskell2010
9−
10−test-suite regression
11−
12− build-depends:
13− base >=4.9 && <4.11,
14− transformers >=0.4.2,
15− mtl >=2.2.1,
16− tasty >=0.10,
17− tasty-quickcheck >=0.8,
18− QuickCheck >=2.8,
19− ghc-prim >=0.3,
20− lens >=4.14,
21− ether
22−
23− main-is:
24− Regression.hs
25−
26− other-modules:
27− Regression.T1
28− Regression.T2
29− Regression.T3
30− Regression.T4
31− Regression.T5
32− Regression.T6
33− Regression.T7
34− Regression.T8
35− Regression.T9
36− Regression.T10
37− Regression.T11
38− Regression.T12
39−
40− type:
41− exitcode-stdio-1.0
42−
43− hs-source-dirs:
44− test
45−
46− default-language:
47− Haskell2010
48−
49− default-extensions:
50− AllowAmbiguousTypes
51− ConstraintKinds
52− DataKinds
53− DeriveGeneric
54− EmptyDataDecls
55− FlexibleContexts
56− FlexibleInstances
57− FunctionalDependencies
58− GADTs
59− GeneralizedNewtypeDeriving
60− PartialTypeSignatures
61− PolyKinds
62− ScopedTypeVariables
63− RankNTypes
64− TemplateHaskell
65− TupleSections
66− TypeApplications
67− TypeFamilies
68− TypeInType
69− TypeOperators
70− TypeSynonymInstances
71− UndecidableInstances
72− UndecidableSuperClasses
73−
74− ghc-options:
75− -Wall -fno-warn-missing-signatures
76−
77−
78−benchmark bench
79−
80− build-depends:
81− base >=4.9 && <4.11,
82− mtl >=2.2.1,
83− transformers >=0.4.2,
84− criterion >=1.1,
85− deepseq >=1.4,
86− lens >=4.14,
87− ether
88−
89− main-is:
90− Bench.hs
91−
92− type:
93− exitcode-stdio-1.0
94−
95− hs-source-dirs:
96− bench
97−
98− default-language:
99− Haskell2010
100−
101− default-extensions:
102− AllowAmbiguousTypes
103− ConstraintKinds
104− DataKinds
105− DeriveGeneric
106− EmptyDataDecls
107− FlexibleContexts
108− FlexibleInstances
109− FunctionalDependencies
110− GADTs
111− GeneralizedNewtypeDeriving
112− PartialTypeSignatures
113− PolyKinds
114− ScopedTypeVariables
115− RankNTypes
116− TemplateHaskell
117− TupleSections
118− TypeApplications
119− TypeFamilies
120− TypeInType
121− TypeOperators
122− TypeSynonymInstances
123− UndecidableInstances
124− UndecidableSuperClasses
125−
126− ghc-options:
127− -Wall -O2
128−
129− ghc-prof-options:
130− -fprof-auto
ether.cabalnew file+237
@@ -0,0 +1,237 @@
1+cabal-version: 2.2
2+name: ether
3+version: 0.5.2.0
4+synopsis: 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
9+category: Control
10+author: Vladislav Zavialov
11+maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
12+homepage: https://int-index.github.io/ether/
13+bug-reports: https://github.com/int-index/ether/issues
14+build-type: Simple
15+extra-source-files: CHANGELOG.md
16+
17+source-repository head
18+
19+ type: git
20+ location: git@github.com:int-index/ether.git
21+
22+
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+
37+library
38+
39+ 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
48+
49+ other-modules:
50+ Ether.Internal.Tags
51+ Ether.Internal.HasLens
52+ Ether.Internal.TH_Utils
53+ Ether.Internal.TH_TupleInstances
54+ Ether.Internal.TupleInstances
55+
56+ 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,
61+ mmorph >=1.0.4,
62+ monad-control >=1.0.0.4,
63+ transformers-base >=0.4.4,
64+ writer-cps-mtl >= 0.1.1.4,
65+ exceptions >=0.8,
66+ template-haskell >=2.11,
67+ tagged >=0.8.5,
68+ reflection >=2.1
69+
70+ default-language:
71+ Haskell2010
72+
73+ default-extensions:
74+ AllowAmbiguousTypes
75+ ConstraintKinds
76+ DataKinds
77+ DeriveGeneric
78+ EmptyDataDecls
79+ FlexibleContexts
80+ FlexibleInstances
81+ FunctionalDependencies
82+ GADTs
83+ GeneralizedNewtypeDeriving
84+ PartialTypeSignatures
85+ PolyKinds
86+ ScopedTypeVariables
87+ RankNTypes
88+ TemplateHaskell
89+ TupleSections
90+ TypeApplications
91+ TypeFamilies
92+ TypeInType
93+ TypeOperators
94+ TypeSynonymInstances
95+ UndecidableInstances
96+ UndecidableSuperClasses
97+
98+ hs-source-dirs:
99+ src
100+
101+ ghc-options:
102+ -Wall -O2
103+
104+ if flag(disable-tup-instances)
105+ cpp-options: -DDISABLE_TUP_INSTANCES
106+
107+test-suite regression
108+
109+ build-depends:
110+ base >=4.9 && <4.13,
111+ transformers >=0.4.2,
112+ mtl >=2.2.1,
113+ tasty >=0.10,
114+ tasty-quickcheck >=0.8,
115+ QuickCheck >=2.8,
116+ ghc-prim >=0.3,
117+ lens >=4.14,
118+ ether
119+
120+ main-is:
121+ Regression.hs
122+
123+ other-modules:
124+ TupleInstances
125+ Regression.T1
126+ Regression.T2
127+ Regression.T3
128+ Regression.T4
129+ Regression.T5
130+ Regression.T6
131+ Regression.T7
132+ Regression.T8
133+ Regression.T9
134+ Regression.T10
135+ Regression.T11
136+ Regression.T12
137+
138+ type:
139+ exitcode-stdio-1.0
140+
141+ hs-source-dirs:
142+ test
143+
144+ default-language:
145+ Haskell2010
146+
147+ default-extensions:
148+ AllowAmbiguousTypes
149+ ConstraintKinds
150+ DataKinds
151+ DeriveGeneric
152+ EmptyDataDecls
153+ FlexibleContexts
154+ FlexibleInstances
155+ FunctionalDependencies
156+ GADTs
157+ GeneralizedNewtypeDeriving
158+ PartialTypeSignatures
159+ PolyKinds
160+ ScopedTypeVariables
161+ RankNTypes
162+ TemplateHaskell
163+ TupleSections
164+ TypeApplications
165+ TypeFamilies
166+ TypeInType
167+ TypeOperators
168+ TypeSynonymInstances
169+ UndecidableInstances
170+ UndecidableSuperClasses
171+
172+ ghc-options:
173+ -Wall -fno-warn-missing-signatures
174+
175+ if flag(disable-tup-instances)
176+ cpp-options: -DDISABLE_TUP_INSTANCES
177+
178+
179+benchmark bench
180+
181+ build-depends:
182+ base >=4.9 && <4.13,
183+ mtl >=2.2.1,
184+ transformers >=0.4.2,
185+ criterion >=1.1,
186+ deepseq >=1.4,
187+ lens >=4.14,
188+ ether
189+
190+ main-is:
191+ Bench.hs
192+
193+ other-modules:
194+ TupleInstances
195+
196+ type:
197+ exitcode-stdio-1.0
198+
199+ hs-source-dirs:
200+ bench
201+
202+ default-language:
203+ Haskell2010
204+
205+ default-extensions:
206+ AllowAmbiguousTypes
207+ ConstraintKinds
208+ DataKinds
209+ DeriveGeneric
210+ EmptyDataDecls
211+ FlexibleContexts
212+ FlexibleInstances
213+ FunctionalDependencies
214+ GADTs
215+ GeneralizedNewtypeDeriving
216+ PartialTypeSignatures
217+ PolyKinds
218+ ScopedTypeVariables
219+ RankNTypes
220+ TemplateHaskell
221+ TupleSections
222+ TypeApplications
223+ TypeFamilies
224+ TypeInType
225+ TypeOperators
226+ TypeSynonymInstances
227+ UndecidableInstances
228+ UndecidableSuperClasses
229+
230+ ghc-options:
231+ -Wall -O2
232+
233+ ghc-prof-options:
234+ -fprof-auto
235+
236+ if flag(disable-tup-instances)
237+ cpp-options: -DDISABLE_TUP_INSTANCES
ether/Setup.hsdeleted−2
@@ -1,2 +0,0 @@
1−import Distribution.Simple
2−main = defaultMain
ether/ether.cabaldeleted−107
@@ -1,107 +0,0 @@
1−name: ether
2−version: 0.5.0.0
3−synopsis: Monad transformers and classes
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−
10−category: Control
11−license: BSD3
12−license-file: LICENSE
13−author: Vladislav Zavialov
14−maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
15−homepage: https://int-index.github.io/ether/
16−bug-reports: https://github.com/int-index/ether/issues
17−build-type: Simple
18−cabal-version: >=1.18
19−extra-source-files: CHANGELOG.md
20−
21−source-repository head
22−
23− type: git
24− location: git@github.com:int-index/ether.git
25−
26−
27−library
28−
29− exposed-modules:
30− Control.Ether.Abbr
31− Control.Ether.Implicit.Abbr
32− Control.Ether.Optic
33− Control.Monad.Trans.Ether.Handler
34− Control.Monad.Ether
35− Control.Monad.Ether.Handle
36− Control.Monad.Ether.TagAttach
37− Control.Monad.Ether.TagReplace
38− Control.Monad.Ether.Reader
39− Control.Monad.Ether.Reader.Class
40− Control.Monad.Ether.Reader.Flatten
41− Control.Monad.Ether.Writer
42− Control.Monad.Ether.Writer.Class
43− Control.Monad.Ether.State
44− Control.Monad.Ether.State.Class
45− Control.Monad.Ether.State.Lazy
46− Control.Monad.Ether.State.Strict
47− Control.Monad.Ether.State.Flatten
48− Control.Monad.Ether.State.Zoom
49− Control.Monad.Ether.Except
50− Control.Monad.Ether.Except.Class
51− Control.Monad.Ether.Implicit
52− Control.Monad.Ether.Implicit.Reader
53− Control.Monad.Ether.Implicit.Writer
54− Control.Monad.Ether.Implicit.State
55− Control.Monad.Ether.Implicit.State.Lazy
56− Control.Monad.Ether.Implicit.State.Strict
57− Control.Monad.Ether.Implicit.Except
58−
59− other-modules:
60− Control.Monad.Ether.State.Common
61−
62− build-depends:
63− base >=4.9 && <4.11,
64− transformers >=0.4.2,
65− transformers-lift >=0.1.0.1,
66− mtl >=2.2.1,
67− mmorph >=1.0.4,
68− monad-control >=1.0.0.4,
69− transformers-base >=0.4.4,
70− exceptions >=0.8,
71− template-haskell >=2.11,
72− tagged >=0.8.5,
73− reflection >=2.1
74−
75− default-language:
76− Haskell2010
77−
78− default-extensions:
79− AllowAmbiguousTypes
80− ConstraintKinds
81− DataKinds
82− DeriveGeneric
83− EmptyDataDecls
84− FlexibleContexts
85− FlexibleInstances
86− FunctionalDependencies
87− GADTs
88− GeneralizedNewtypeDeriving
89− PartialTypeSignatures
90− PolyKinds
91− ScopedTypeVariables
92− RankNTypes
93− TemplateHaskell
94− TupleSections
95− TypeApplications
96− TypeFamilies
97− TypeInType
98− TypeOperators
99− TypeSynonymInstances
100− UndecidableInstances
101− UndecidableSuperClasses
102−
103− hs-source-dirs:
104− src
105−
106− ghc-options:
107− -Wall -O2
ether/src/Control/Ether/Abbr.hsdeleted−61
@@ -1,61 +0,0 @@
1−-- | Abbreviations for constraints.
2−
3−module Control.Ether.Abbr
4− ( type (-->)
5− , type (<--)
6− , type (<->)
7− , type (-!-)
8− , Ether
9− , ReifyAbbr
10− ) where
11−
12−import Data.Kind as K
13−import GHC.Exts (Constraint)
14−
15−import Control.Monad.Ether
16−
17−-- | Turns an abbreviation into an actual constraint.
18−type family ReifyAbbr (abbr :: k) :: (K.Type -> K.Type) -> Constraint
19−
20−-- | Denotes 'MonadReader'. The mnemonic is that you read values of type @r@
21−-- from the reader environment tagged by @tag@, thus the arrows points
22−-- from @tag@ to @r@.
23−data tag --> r
24−type instance ReifyAbbr (tag --> r) = MonadReader tag r
25−
26−-- | Denotes 'MonadWriter'. The mnemonic is that you write values of type @w@
27−-- to the writer accumulator tagged by @tag@, thus the arrows points
28−-- from @w@ to @tag@.
29−data tag <-- w
30−type instance ReifyAbbr (tag <-- w) = MonadWriter tag w
31−
32−-- | Denotes 'MonadState'. The mnemonic is that you can both read from and
33−-- write into the state, thus the arrow points in both directions.
34−data tag <-> s
35−type instance ReifyAbbr (tag <-> s) = MonadState tag s
36−
37−-- | Denotes 'MonadExcept'.
38−data tag -!- e
39−type instance ReifyAbbr (tag -!- e) = MonadExcept tag e
40−
41−-- | Reify a list of constraint abbreviations.
42−--
43−-- > f :: Ether '[Foo --> r, Bar <-- w, Baz <-> s, Quux -!- e] m => m a
44−--
45−-- expands into
46−--
47−-- > f :: ( MonadReader Foo r m
48−-- > , MonadWriter Bar w m
49−-- > , MonadState Baz s m
50−-- > , MonadExcept Quux e m
51−-- > ) => m a
52−
53−class U a
54−instance U a
55−
56−class (c a, d a) => (c &&& d) a
57−instance (c a, d a) => (c &&& d) a
58−
59−type family Ether (abbrs :: [K.Type]) :: (K.Type -> K.Type) -> Constraint where
60− Ether '[] = U
61− Ether (abbr ': abbrs) = ReifyAbbr abbr &&& Ether abbrs
ether/src/Control/Ether/Implicit/Abbr.hsdeleted−23
@@ -1,23 +0,0 @@
1−-- | See "Control.Ether.Abbr".
2−
3−module Control.Ether.Implicit.Abbr (R, W, S, E) where
4−
5−import Control.Ether.Abbr (ReifyAbbr)
6−import Control.Monad.Ether.Implicit
7−
8−-- | Denotes 'MonadReader'.
9−data R r
10−type instance ReifyAbbr (R r) = MonadReader r
11−
12−-- | Denotes 'MonadWriter'.
13−data W w
14−type instance ReifyAbbr (W w) = MonadWriter w
15−
16−-- | Denotes 'MonadState'.
17−data S s
18−type instance ReifyAbbr (S s) = MonadState s
19−
20−-- | Denotes 'MonadExcept'.
21−data E e
22−type instance ReifyAbbr (E e) = MonadExcept e
23−
ether/src/Control/Ether/Optic.hsdeleted−142
@@ -1,142 +0,0 @@
1−module Control.Ether.Optic
2− ( Tagged(..)
3− , TagsK
4− , Tags
5− , HasLens(..)
6− , LensLike
7− , Lens
8− , Lens'
9− , view
10− , over
11− , HList(..)
12− , KindOf
13− ) where
14−
15−import Control.Applicative
16−import Control.Monad
17−import Data.Functor.Identity
18−import Data.Kind as K
19−import Data.List as List
20−import Data.Tagged
21−import Data.Traversable
22−import Language.Haskell.TH
23−import Data.Coerce
24−
25−type LensLike f s t a b = (a -> f b) -> s -> f t
26−
27−type Lens s t a b = forall f. Functor f => LensLike f s t a b
28−
29−type Lens' s a = Lens s s a a
30−
31−class HasLens tag outer inner | tag outer -> inner where
32− lensOf :: Lens' outer inner
33−
34−instance HasLens a a a where
35− lensOf = id
36− {-# INLINE lensOf #-}
37−
38−view :: LensLike (Const a) s t a b -> s -> a
39−view l = coerce (l Const)
40−{-# INLINE view #-}
41−
42−over :: LensLike Identity s t a b -> (a -> b) -> s -> t
43−over = coerce
44−{-# INLINE over #-}
45−
46−data HList xs where
47− HNil :: HList '[]
48− HCons :: x -> HList xs -> HList (x ': xs)
49−
50−type KindOf (a :: k) = k
51−
52−type family TagsK (p :: K.Type) :: [K.Type]
53−type family Tags (p :: K.Type) :: HList (TagsK p)
54−
55−return []
56−
57−type instance TagsK () = '[]
58−type instance TagsK (Tagged t a) = '[KindOf t]
59−type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
60−
61−return []
62−
63−type instance Tags () = 'HNil
64−type instance Tags (Tagged t a) = 'HCons t 'HNil
65−type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
66−
67−do
68− let
69− tupCount = 62
70− names = [1..] >>= flip replicateM ['a'..'z']
71− varNames <- traverse newName (take tupCount names)
72− fmap List.concat $
73− for (List.drop 2 (List.inits varNames)) $
74− \varNames' -> do
75− let n = List.length varNames'
76− tagsInstances <- for [() | n > 2] $ \() -> do
77− tag <- newName "tag"
78− let
79− (cur:rest) = varNames'
80− tupTy = foldl AppT (ConT (tupleTypeName n))
81− ( ConT ''Tagged `AppT` VarT tag `AppT` VarT cur :
82− map VarT rest )
83− tupTy' = foldl AppT (ConT (tupleTypeName (n-1)))
84− (map VarT rest)
85− return $
86− TySynInstD ''TagsK (TySynEqn [tupTy]
87− ( PromotedConsT `AppT` (ConT ''KindOf `AppT` VarT tag) `AppT`
88− (ConT ''TagsK `AppT` tupTy') ))
89− return tagsInstances
90−do
91− let
92− tupCount = 62
93− names = [1..] >>= flip replicateM ['a'..'z']
94− varNames <- traverse newName (take tupCount names)
95− fmap List.concat $
96− for (List.drop 2 (List.inits varNames)) $
97− \varNames' -> do
98− let n = List.length varNames'
99− tagsInstances <- for [() | n > 2] $ \() -> do
100− tag <- newName "tag"
101− let
102− (cur:rest) = varNames'
103− tupTy = foldl AppT (ConT (tupleTypeName n))
104− ( ConT ''Tagged `AppT` VarT tag `AppT` VarT cur :
105− map VarT rest )
106− tupTy' = foldl AppT (ConT (tupleTypeName (n-1)))
107− (map VarT rest)
108− tagsInst =
109− TySynInstD ''Tags (TySynEqn [tupTy]
110− ( PromotedT 'HCons `AppT` VarT tag `AppT`
111− (ConT ''Tags `AppT` tupTy') ))
112− return tagsInst
113− hasLensInstances <- for [0..n-1] $ \k -> do
114− tag <- newName "tag"
115− let
116− (prev, cur:next) = List.splitAt k varNames'
117− tupTy = foldl AppT (ConT (tupleTypeName n))
118− ( map VarT prev ++
119− [ConT ''Tagged `AppT` VarT tag `AppT` VarT cur] ++
120− map VarT next )
121− cur' <- newName "x"
122− f <- newName "f"
123− return $
124− InstanceD Nothing []
125− (ConT ''HasLens `AppT` VarT tag `AppT` tupTy `AppT` VarT cur)
126− [ FunD 'lensOf
127− [ Clause
128− [VarP f, TupP
129− ( map VarP prev ++
130− [ConP 'Tagged [VarP cur]] ++
131− map VarP next )]
132− (NormalB $
133− VarE 'fmap `AppE`
134− (LamE [VarP cur']
135− (TupE
136− ( map VarE prev ++
137− [ConE 'Tagged `AppE` VarE cur'] ++
138− map VarE next ))) `AppE`
139− (VarE f `AppE` VarE cur) )
140− [] ],
141− PragmaD (InlineP 'lensOf Inline FunLike AllPhases) ]
142− return $ tagsInstances ++ hasLensInstances
ether/src/Control/Monad/Ether.hsdeleted−13
@@ -1,13 +0,0 @@
1−-- | This module provides convenience exports of all
2−-- tagged monad classes from Ether.
3−
4−module Control.Monad.Ether (module X) where
5−
6−import Control.Monad as X
7−import Control.Monad.Fix as X
8−import Control.Monad.Ether.Reader as X
9−import Control.Monad.Ether.Writer as X
10−import Control.Monad.Ether.State as X
11−import Control.Monad.Ether.Except as X
12−import Control.Monad.Ether.TagAttach as X
13−import Control.Monad.Ether.TagReplace as X
ether/src/Control/Monad/Ether/Except.hsdeleted−89
@@ -1,89 +0,0 @@
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 #-}
ether/src/Control/Monad/Ether/Except/Class.hsdeleted−29
@@ -1,29 +0,0 @@
1−-- | See "Control.Monad.Except".
2−
3−module Control.Monad.Ether.Except.Class
4− ( MonadExcept(..)
5− ) where
6−
7−import qualified Control.Monad.Trans.Lift.Catch as Lift
8−
9−-- | See 'Control.Monad.Except.MonadError'.
10−class Monad m => MonadExcept tag e m | m tag -> e where
11−
12− -- | Is used within a monadic computation to begin exception processing.
13− throw :: e -> m a
14−
15− -- | A handler function to handle previous exceptions and return to
16− -- normal execution.
17− catch :: m a -> (e -> m a) -> m a
18−
19−instance {-# OVERLAPPABLE #-}
20− ( Lift.LiftCatch t
21− , Monad (t m)
22− , MonadExcept tag e m
23− ) => MonadExcept tag e (t m) where
24−
25− throw = Lift.lift . throw @tag
26− {-# INLINE throw #-}
27−
28− catch = Lift.liftCatch (catch @tag)
29− {-# INLINE catch #-}
ether/src/Control/Monad/Ether/Handle.hsdeleted−35
@@ -1,35 +0,0 @@
1−module Control.Monad.Ether.Handle
2− ( Handle(..)
3− , HandleSuper
4− , HandleConstraint
5− , TAGGED
6− ) where
7−
8−import Data.Kind as K
9−import GHC.Exts (Constraint)
10−
11−data TAGGED e t
12−
13−type K_Monad = K.Type -> K.Type
14−
15−type K_Trans = K_Monad -> K_Monad
16−
17−type family
18− HandleSuper
19− (eff :: keff)
20− (p :: kp)
21− (trans :: K_Trans)
22− :: Constraint
23−
24−type family
25− HandleConstraint
26− (eff :: keff)
27− (p :: kp)
28− (trans :: K_Trans) (m :: K_Monad)
29− :: Constraint
30−
31−class
32− HandleSuper eff p trans =>
33− Handle eff p (trans :: K_Trans) | eff trans -> p
34− where
35− handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
ether/src/Control/Monad/Ether/Implicit.hsdeleted−13
@@ -1,13 +0,0 @@
1−-- | This module provides convenience exports of all
2−-- implicitly tagged monad classes from Ether.
3−
4−module Control.Monad.Ether.Implicit (module X) where
5−
6−import Control.Monad as X
7−import Control.Monad.Fix as X
8−import Control.Monad.Ether.Implicit.Reader as X
9−import Control.Monad.Ether.Implicit.Writer as X
10−import Control.Monad.Ether.Implicit.State as X
11−import Control.Monad.Ether.Implicit.Except as X
12−import Control.Monad.Ether.TagAttach as X
13−import Control.Monad.Ether.TagReplace as X
ether/src/Control/Monad/Ether/Implicit/Except.hsdeleted−58
@@ -1,58 +0,0 @@
1−-- | See "Control.Monad.Ether.Except".
2−
3−module Control.Monad.Ether.Implicit.Except
4− (
5− -- * MonadExcept class
6− MonadExcept
7− , throw
8− , catch
9− -- * The Except monad
10− , Except
11− , runExcept
12− -- * The ExceptT monad transformer
13− , ExceptT
14− , exceptT
15− , runExceptT
16− -- * Handle functions
17− , handle
18− , handleT
19− ) where
20−
21−import qualified Control.Monad.Ether.Except as A
22−
23−-- | See 'Control.Monad.Ether.Except.MonadExcept'.
24−type MonadExcept e = A.MonadExcept e e
25−
26−-- | See 'Control.Monad.Ether.Except.throw'.
27−throw :: forall e m a . MonadExcept e m => e -> m a
28−throw = A.throw @e
29−
30−-- | See 'Control.Monad.Ether.Except.catch'.
31−catch :: forall e m a . MonadExcept e m => m a -> (e -> m a) -> m a
32−catch = A.catch @e
33−
34−-- | See 'Control.Monad.Ether.Except.Except'.
35−type Except e = A.Except e e
36−
37−-- | See 'Control.Monad.Ether.Except.runExcept'.
38−runExcept :: Except e a -> Either e a
39−runExcept = A.runExcept
40−
41−-- | See 'Control.Monad.Ether.Except.ExceptT'.
42−type ExceptT e = A.ExceptT e e
43−
44−-- | See 'Control.Monad.Ether.Except.exceptT'.
45−exceptT :: m (Either e a) -> ExceptT e m a
46−exceptT = A.exceptT
47−
48−-- | See 'Control.Monad.Ether.Except.runExceptT'.
49−runExceptT :: ExceptT e m a -> m (Either e a)
50−runExceptT = A.runExceptT
51−
52−-- | See 'Control.Monad.Ether.Except.handle'.
53−handle :: (e -> a) -> Except e a -> a
54−handle = A.handle
55−
56−-- | See 'Control.Monad.Ether.Except.handleT'.
57−handleT :: Functor m => (e -> a) -> ExceptT e m a -> m a
58−handleT = A.handleT
ether/src/Control/Monad/Ether/Implicit/Reader.hsdeleted−57
@@ -1,57 +0,0 @@
1−-- | See "Control.Monad.Ether.Reader".
2−
3−module Control.Monad.Ether.Implicit.Reader
4− (
5− -- * MonadReader class
6− MonadReader
7− , local
8− , ask
9− , reader
10− , asks
11− -- * The Reader monad
12− , Reader
13− , runReader
14− -- * The ReaderT monad transformer
15− , ReaderT
16− , readerT
17− , runReaderT
18− ) where
19−
20−import qualified Control.Monad.Ether.Reader as A
21−
22−-- | See 'Control.Monad.Ether.Reader.ReaderT'.
23−type ReaderT r = A.ReaderT r r
24−
25−-- | See 'Control.Monad.Ether.Reader.readerT'.
26−readerT :: (r -> m a) -> ReaderT r m a
27−readerT = A.readerT
28−
29−-- | See 'Control.Monad.Ether.Reader.runReaderT'.
30−runReaderT :: ReaderT r m a -> r -> m a
31−runReaderT = A.runReaderT
32−
33−-- | See 'Control.Monad.Ether.Reader.Reader'.
34−type Reader r = A.Reader r r
35−
36−-- | See 'Control.Monad.Ether.Reader.runReader'.
37−runReader :: Reader r a -> r -> a
38−runReader = A.runReader
39−
40−-- | See 'Control.Monad.Ether.Reader.MonadReader'.
41−type MonadReader r = A.MonadReader r r
42−
43−-- | See 'Control.Monad.Ether.Reader.local'.
44−local :: forall r m a . MonadReader r m => (r -> r) -> m a -> m a
45−local = A.local @r
46−
47−-- | See 'Control.Monad.Ether.Reader.ask'.
48−ask :: forall r m . MonadReader r m => m r
49−ask = A.ask @r
50−
51−-- | See 'Control.Monad.Ether.Reader.reader'.
52−reader :: forall r m a . MonadReader r m => (r -> a) -> m a
53−reader = A.reader @r
54−
55−-- | See 'Control.Monad.Ether.Reader.asks'.
56−asks :: forall r m a . MonadReader r m => (r -> a) -> m a
57−asks = A.asks @r
ether/src/Control/Monad/Ether/Implicit/State.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- | See "Control.Monad.Ether.State".
2−
3−module Control.Monad.Ether.Implicit.State
4− ( module Control.Monad.Ether.Implicit.State.Lazy
5− ) where
6−
7−import Control.Monad.Ether.Implicit.State.Lazy
ether/src/Control/Monad/Ether/Implicit/State/Lazy.hsdeleted−82
@@ -1,82 +0,0 @@
1−-- | See "Control.Monad.Ether.State.Lazy".
2−
3−module Control.Monad.Ether.Implicit.State.Lazy
4− (
5− -- * MonadState class
6− MonadState
7− , get
8− , put
9− , state
10− , modify
11− , gets
12− -- * The State monad
13− , State
14− , runState
15− , evalState
16− , execState
17− -- * The StateT monad transformer
18− , StateT
19− , stateT
20− , runStateT
21− , evalStateT
22− , execStateT
23− ) where
24−
25−import qualified Control.Monad.Ether.State.Lazy as A
26−
27−-- | See 'Control.Monad.Ether.State.Lazy.StateT'.
28−type StateT s = A.StateT s s
29−
30−-- | See 'Control.Monad.Ether.State.Lazy.stateT'.
31−stateT :: (s -> m (a, s)) -> StateT s m a
32−stateT = A.stateT
33−
34−-- | See 'Control.Monad.Ether.State.Lazy.runStateT'.
35−runStateT :: StateT s m a -> s -> m (a, s)
36−runStateT = A.runStateT
37−
38−-- | See 'Control.Monad.Ether.State.Lazy.runState'.
39−runState :: State s a -> s -> (a, s)
40−runState = A.runState
41−
42−-- | See 'Control.Monad.Ether.State.Lazy.evalStateT'.
43−evalStateT :: Monad m => StateT s m a -> s -> m a
44−evalStateT = A.evalStateT
45−
46−-- | See 'Control.Monad.Ether.State.Lazy.State'.
47−type State s = A.State s s
48−
49−-- | See 'Control.Monad.Ether.State.Lazy.evalState'.
50−evalState :: State s a -> s -> a
51−evalState = A.evalState
52−
53−-- | See 'Control.Monad.Ether.State.Lazy.execStateT'.
54−execStateT :: Monad m => StateT s m a -> s -> m s
55−execStateT = A.execStateT
56−
57−-- | See 'Control.Monad.Ether.State.Lazy.execState'.
58−execState :: State s a -> s -> s
59−execState = A.execState
60−
61−-- | See 'Control.Monad.Ether.State.Lazy.MonadState'.
62−type MonadState s = A.MonadState s s
63−
64−-- | See 'Control.Monad.Ether.State.Lazy.get'.
65−get :: forall s m . MonadState s m => m s
66−get = A.get @s
67−
68−-- | See 'Control.Monad.Ether.State.Lazy.gets'.
69−gets :: forall s m a . MonadState s m => (s -> a) -> m a
70−gets = A.gets @s
71−
72−-- | See 'Control.Monad.Ether.State.Lazy.put'.
73−put :: forall s m . MonadState s m => s -> m ()
74−put = A.put @s
75−
76−-- | See 'Control.Monad.Ether.State.Lazy.state'.
77−state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
78−state = A.state @s
79−
80−-- | See 'Control.Monad.Ether.State.Lazy.modify'.
81−modify :: forall s m . MonadState s m => (s -> s) -> m ()
82−modify = A.modify @s
ether/src/Control/Monad/Ether/Implicit/State/Strict.hsdeleted−82
@@ -1,82 +0,0 @@
1−-- | See "Control.Monad.Ether.State.Strict".
2−
3−module Control.Monad.Ether.Implicit.State.Strict
4− (
5− -- * MonadState class
6− MonadState
7− , get
8− , put
9− , state
10− , modify
11− , gets
12− -- * The State monad
13− , State
14− , runState
15− , evalState
16− , execState
17− -- * The StateT monad transformer
18− , StateT
19− , stateT
20− , runStateT
21− , evalStateT
22− , execStateT
23− ) where
24−
25−import qualified Control.Monad.Ether.State.Strict as A
26−
27−-- | See 'Control.Monad.Ether.State.Strict.StateT'.
28−type StateT s = A.StateT s s
29−
30−-- | See 'Control.Monad.Ether.State.Strict.stateT'.
31−stateT :: (s -> m (a, s)) -> StateT s m a
32−stateT = A.stateT
33−
34−-- | See 'Control.Monad.Ether.State.Strict.runStateT'.
35−runStateT :: StateT s m a -> s -> m (a, s)
36−runStateT = A.runStateT
37−
38−-- | See 'Control.Monad.Ether.State.Strict.runState'.
39−runState :: State s a -> s -> (a, s)
40−runState = A.runState
41−
42−-- | See 'Control.Monad.Ether.State.Strict.evalStateT'.
43−evalStateT :: Monad m => StateT s m a -> s -> m a
44−evalStateT = A.evalStateT
45−
46−-- | See 'Control.Monad.Ether.State.Strict.State'.
47−type State s = A.State s s
48−
49−-- | See 'Control.Monad.Ether.State.Strict.evalState'.
50−evalState :: State s a -> s -> a
51−evalState = A.evalState
52−
53−-- | See 'Control.Monad.Ether.State.Strict.execStateT'.
54−execStateT :: Monad m => StateT s m a -> s -> m s
55−execStateT = A.execStateT
56−
57−-- | See 'Control.Monad.Ether.State.Strict.execState'.
58−execState :: State s a -> s -> s
59−execState = A.execState
60−
61−-- | See 'Control.Monad.Ether.State.Strict.MonadState'.
62−type MonadState s = A.MonadState s s
63−
64−-- | See 'Control.Monad.Ether.State.Strict.get'.
65−get :: forall s m . MonadState s m => m s
66−get = A.get @s
67−
68−-- | See 'Control.Monad.Ether.State.Strict.gets'.
69−gets :: forall s m a . MonadState s m => (s -> a) -> m a
70−gets = A.gets @s
71−
72−-- | See 'Control.Monad.Ether.State.Strict.put'.
73−put :: forall s m . MonadState s m => s -> m ()
74−put = A.put @s
75−
76−-- | See 'Control.Monad.Ether.State.Strict.state'.
77−state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
78−state = A.state @s
79−
80−-- | See 'Control.Monad.Ether.State.Strict.modify'.
81−modify :: forall s m . MonadState s m => (s -> s) -> m ()
82−modify = A.modify @s
ether/src/Control/Monad/Ether/Implicit/Writer.hsdeleted−77
@@ -1,77 +0,0 @@
1−-- | See "Control.Monad.Ether.Writer".
2−
3−module Control.Monad.Ether.Implicit.Writer
4− (
5− -- * MonadWriter class
6− MonadWriter
7− , writer
8− , tell
9− , listen
10− , pass
11− , listens
12− , censor
13− -- * The Writer monad
14− , Writer
15− , runWriter
16− , execWriter
17− -- * The WriterT monad transformer
18− , WriterT
19− , writerT
20− , runWriterT
21− , execWriterT
22− ) where
23−
24−import qualified Control.Monad.Ether.Writer as A
25−
26−-- | See 'Control.Monad.Ether.Writer.MonadWriter'.
27−type MonadWriter w = A.MonadWriter w w
28−
29−-- | See 'Control.Monad.Ether.Writer.writer'.
30−writer :: forall w m a . MonadWriter w m => (a, w) -> m a
31−writer = A.writer @w
32−
33−-- | See 'Control.Monad.Ether.Writer.tell'.
34−tell :: forall w m . MonadWriter w m => w -> m ()
35−tell = A.tell @w
36−
37−-- | See 'Control.Monad.Ether.Writer.listen'.
38−listen :: forall w m a . MonadWriter w m => m a -> m (a, w)
39−listen = A.listen @w
40−
41−-- | See 'Control.Monad.Ether.Writer.pass'.
42−pass :: forall w m a . MonadWriter w m => m (a, w -> w) -> m a
43−pass = A.pass @w
44−
45−-- | See 'Control.Monad.Ether.Writer.listens'.
46−listens :: forall w m a b . MonadWriter w m => (w -> b) -> m a -> m (a, b)
47−listens = A.listens @w
48−
49−-- | See 'Control.Monad.Ether.Writer.censor'.
50−censor :: forall w m a . MonadWriter w m => (w -> w) -> m a -> m a
51−censor = A.censor @w
52−
53−-- | See 'Control.Monad.Ether.Writer.Writer'.
54−type Writer w = A.Writer w w
55−
56−-- | See 'Control.Monad.Ether.Writer.runWriter'.
57−runWriter :: Writer w a -> (a, w)
58−runWriter = A.runWriter
59−
60−-- | See 'Control.Monad.Ether.Writer.execWriter'.
61−execWriter :: Writer w a -> w
62−execWriter = A.execWriter
63−
64−-- | See 'Control.Monad.Ether.Writer.WriterT'.
65−type WriterT w = A.WriterT w w
66−
67−-- | See 'Control.Monad.Ether.Writer.writerT'.
68−writerT :: m (a, w) -> WriterT w m a
69−writerT = A.writerT
70−
71−-- | See 'Control.Monad.Ether.Writer.runWriterT'.
72−runWriterT :: WriterT w m a -> m (a, w)
73−runWriterT = A.runWriterT
74−
75−-- | See 'Control.Monad.Ether.Writer.execWriterT'.
76−execWriterT :: Monad m => WriterT w m a -> m w
77−execWriterT = A.execWriterT
ether/src/Control/Monad/Ether/Reader.hsdeleted−128
@@ -1,128 +0,0 @@
1−-- | See "Control.Monad.Reader".
2−
3−module Control.Monad.Ether.Reader
4− (
5− -- * MonadReader class
6− MonadReader
7− , ask
8− , local
9− , reader
10− , asks
11− -- * The Reader monad
12− , Reader
13− , runReader
14− -- * The ReaderT monad transformer
15− , ReaderT
16− , readerT
17− , runReaderT
18− -- *
19− , READER
20− ) where
21−
22−import Control.Monad.Ether.Handle
23−import Control.Monad.Ether.Reader.Class
24−import Control.Ether.Optic
25−import Control.Monad.Trans.Ether.Handler
26−import Control.Monad.Trans.Lift.Local (Local)
27−import qualified Control.Monad.Reader as T
28−import Data.Functor.Identity
29−import Data.Coerce
30−
31−-- | Retrieves a function of the current environment.
32−asks
33− :: forall tag r m a
34− . MonadReader tag r m
35− => (r -> a)
36− -- ^ The selector function to apply to the environment.
37− -> m a
38−asks = reader @tag
39−{-# INLINE asks #-}
40−
41−-- | Encode type-level information for 'ReaderT'.
42−data READER
43−
44−-- | The parameterizable reader monad.
45−--
46−-- Computations are functions of a shared environment.
47−--
48−-- The 'return' function ignores the environment, while '>>=' passes
49−-- the inherited environment to both subcomputations.
50−type Reader tag r = ReaderT tag r Identity
51−
52−-- | The reader monad transformer,
53−-- which adds a read-only environment to the given monad.
54−--
55−-- The 'return' function ignores the environment, while '>>=' passes
56−-- the inherited environment to both subcomputations.
57−type ReaderT tag r = Handler (TAGGED READER tag) (T.ReaderT r)
58−
59−-- | Constructor for computations in the reader monad transformer.
60−readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
61−readerT = coerce (T.ReaderT @r @m @a)
62−{-# INLINE readerT #-}
63−
64−-- | Runs a 'ReaderT' with the given environment
65−-- and returns the final value.
66−runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
67−runReaderT = coerce (T.runReaderT @r @_ @m @a)
68−{-# INLINE runReaderT #-}
69−
70−-- | Runs a 'ReaderT' with the given environment
71−-- and returns the final value.
72−runReader :: forall tag r a . Reader tag r a -> r -> a
73−runReader = coerce (T.runReader @r @a)
74−{-# INLINE runReader #-}
75−
76−type instance HandleSuper READER r trans = ()
77−type instance HandleConstraint READER r trans m =
78− T.MonadReader r (trans m)
79−
80−instance Handle READER r (T.ReaderT r) where
81− handling r = r
82− {-# INLINE handling #-}
83−
84−instance
85− ( Handle READER r trans
86− , Monad m, Monad (trans m)
87− ) => MonadReader tag r (Handler (TAGGED READER tag) trans m)
88− where
89−
90− ask =
91− handling @READER @r @trans @m $
92− coerce (T.ask @r @(trans m))
93− {-# INLINE ask #-}
94−
95− local =
96− handling @READER @r @trans @m $
97− coerce (T.local @r @(trans m) @a) ::
98− forall 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 #-}
ether/src/Control/Monad/Ether/Reader/Class.hsdeleted−77
@@ -1,77 +0,0 @@
1−-- | See "Control.Monad.Reader.Class".
2−
3−module Control.Monad.Ether.Reader.Class
4− ( MonadReader(..)
5− ) where
6−
7−import Data.Kind as K
8−import Control.Monad.Trans.Ether.Handler
9−import qualified Control.Monad.Trans.Lift.Local as Lift
10−import Data.Coerce
11−
12−-- | See 'Control.Monad.Reader.MonadReader'.
13−class Monad m => MonadReader tag r m | m tag -> r where
14−
15− {-# MINIMAL (ask | reader), local #-}
16−
17− -- | Retrieves the monad environment.
18− ask :: m r
19− ask = reader @tag id
20−
21− -- | Executes a computation in a modified environment.
22− local
23− :: (r -> r)
24− -- ^ The function to modify the environment.
25− -> m a
26− -- ^ @Reader@ to run in the modified environment.
27− -> m a
28−
29− -- | Retrieves a function of the current environment.
30− reader
31− :: (r -> a)
32− -- ^ The selector function to apply to the environment.
33− -> m a
34− reader f = fmap f (ask @tag)
35−
36−instance {-# OVERLAPPABLE #-}
37− ( Lift.LiftLocal t
38− , Monad (t m)
39− , MonadReader tag r m
40− ) => MonadReader tag r (t m)
41− where
42−
43− ask = Lift.lift (ask @tag)
44− {-# INLINE ask #-}
45−
46− local = Lift.liftLocal (ask @tag) (local @tag)
47− {-# INLINE local #-}
48−
49− reader = Lift.lift . reader @tag
50− {-# INLINE reader #-}
51−
52−instance {-# OVERLAPPABLE #-}
53− ( Monad (trans m)
54− , MonadReader tag r (Handler 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 #-}
ether/src/Control/Monad/Ether/Reader/Flatten.hsdeleted−29
@@ -1,29 +0,0 @@
1−module Control.Monad.Ether.Reader.Flatten
2− ( ReaderT
3− , runReaderT
4− , Reader
5− , runReader
6− ) where
7−
8−import Control.Ether.Optic
9−import Control.Monad.Ether.Handle
10−import Control.Monad.Ether.Reader (READER)
11−import qualified Control.Monad.Reader as T
12−import Control.Monad.Trans.Ether.Handler
13−import Data.Coerce
14−import Data.Functor.Identity
15−import Data.Kind
16−
17−type family READERS (ts :: HList xs) :: [Type] where
18− READERS 'HNil = '[]
19− READERS ('HCons t ts) = TAGGED READER t ': READERS ts
20−
21−type ReaderT r = Handler (READERS (Tags r)) (T.ReaderT r)
22−
23−type Reader r = ReaderT r Identity
24−
25−runReaderT :: forall p m a . ReaderT p m a -> p -> m a
26−runReaderT = coerce (T.runReaderT @p @_ @m @a)
27−
28−runReader :: forall p a . Reader p a -> p -> a
29−runReader = coerce (T.runReader @p @a)
ether/src/Control/Monad/Ether/State.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- | See "Control.Monad.State".
2−
3−module Control.Monad.Ether.State
4− ( module Control.Monad.Ether.State.Lazy
5− ) where
6−
7−import Control.Monad.Ether.State.Lazy
ether/src/Control/Monad/Ether/State/Class.hsdeleted−74
@@ -1,74 +0,0 @@
1−-- | See "Control.Monad.State.Class".
2−
3−module Control.Monad.Ether.State.Class
4− ( MonadState(..)
5− ) where
6−
7−import Data.Kind as K
8−import Control.Monad.Trans.Ether.Handler
9−import qualified Control.Monad.Trans as Lift
10−import Data.Coerce
11−
12−-- | See 'Control.Monad.State.MonadState'.
13−class Monad m => MonadState tag s m | m tag -> s where
14−
15− {-# MINIMAL state | get, put #-}
16−
17− -- | Return the state from the internals of the monad.
18− get :: m s
19− get = state @tag (\s -> (s, s))
20−
21− -- | Replace the state inside the monad.
22− put :: s -> m ()
23− put s = state @tag (\_ -> ((), s))
24−
25− -- | Embed a simple state action into the monad.
26− state :: (s -> (a, s)) -> m a
27− state f = do
28− s <- get @tag
29− let ~(a, s') = f s
30− put @tag s'
31− return a
32−
33−instance {-# OVERLAPPABLE #-}
34− ( Lift.MonadTrans t
35− , Monad (t m)
36− , MonadState tag s m
37− ) => MonadState tag s (t m)
38− where
39−
40− get = Lift.lift (get @tag)
41− {-# INLINE get #-}
42−
43− put = Lift.lift . put @tag
44− {-# INLINE put #-}
45−
46− state = Lift.lift . state @tag
47− {-# INLINE state #-}
48−
49−instance {-# OVERLAPPABLE #-}
50− ( Monad (trans m)
51− , MonadState tag s (Handler 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 #-}
ether/src/Control/Monad/Ether/State/Common.hsdeleted−90
@@ -1,90 +0,0 @@
1−module Control.Monad.Ether.State.Common
2− ( MonadState
3− , get
4− , put
5− , state
6− , modify
7− , gets
8− , STATE
9− ) where
10−
11−import Control.Ether.Optic
12−import Control.Monad.Ether.Handle
13−import Control.Monad.Ether.State.Class
14−import qualified Control.Monad.State as T
15−import Control.Monad.Trans.Ether.Handler
16−import Data.Coerce
17−
18−-- | Encode type-level information for 'StateT'.
19−data STATE
20−
21−-- | Modifies the state inside a state monad.
22−modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
23−modify f = state @tag (\s -> ((), f s))
24−{-# INLINABLE modify #-}
25−
26−-- | Gets specific component of the state, using a projection function supplied.
27−gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
28−gets f = fmap f (get @tag)
29−{-# INLINABLE gets #-}
30−
31−type instance HandleSuper STATE s trans = ()
32−type instance HandleConstraint STATE s trans m =
33− T.MonadState s (trans m)
34−
35−instance Handle STATE s (T.StateT s) where
36− handling r = r
37− {-# INLINE handling #-}
38−
39−instance
40− ( Handle STATE s trans
41− , Monad m, Monad (trans m)
42− ) => MonadState tag s (Handler (TAGGED STATE tag) trans m)
43− where
44−
45− get =
46− handling @STATE @s @trans @m $
47− coerce (T.get @s @(trans m))
48− {-# INLINE get #-}
49−
50− put =
51− handling @STATE @s @trans @m $
52− coerce (T.put @s @(trans m))
53− {-# INLINE put #-}
54−
55− state =
56− handling @STATE @s @trans @m $
57− coerce (T.state @s @(trans m) @a) ::
58− forall 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 #-}
ether/src/Control/Monad/Ether/State/Flatten.hsdeleted−29
@@ -1,29 +0,0 @@
1−module Control.Monad.Ether.State.Flatten
2− ( StateT
3− , runStateT
4− , State
5− , runState
6− ) where
7−
8−import Control.Ether.Optic
9−import Control.Monad.Ether.Handle
10−import Control.Monad.Ether.State (STATE)
11−import qualified Control.Monad.State as T
12−import Control.Monad.Trans.Ether.Handler
13−import Data.Coerce
14−import Data.Functor.Identity
15−import Data.Kind
16−
17−type family STATES (ts :: HList xs) :: [Type] where
18− STATES 'HNil = '[]
19− STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
20−
21−type StateT s = Handler (STATES (Tags s)) (T.StateT s)
22−
23−type State s = StateT s Identity
24−
25−runStateT :: forall p m a . StateT p m a -> p -> m (a, p)
26−runStateT = coerce (T.runStateT @p @m @a)
27−
28−runState :: forall p a . State p a -> p -> (a, p)
29−runState = coerce (T.runState @p @a)
ether/src/Control/Monad/Ether/State/Lazy.hsdeleted−87
@@ -1,87 +0,0 @@
1−-- | See "Control.Monad.State.Lazy".
2−
3−module Control.Monad.Ether.State.Lazy
4− (
5− -- * MonadState class
6− MonadState
7− , get
8− , put
9− , state
10− , modify
11− , gets
12− -- * The State monad
13− , State
14− , runState
15− , evalState
16− , execState
17− -- * The StateT monad transformer
18− , StateT
19− , stateT
20− , runStateT
21− , evalStateT
22− , execStateT
23− -- *
24− , STATE
25− ) where
26−
27−import Control.Monad.Ether.Handle
28−import Control.Monad.Ether.State.Common
29−import qualified Control.Monad.Trans.Ether.Handler as D
30−import qualified Control.Monad.Trans.State.Lazy as T
31−import Data.Functor.Identity
32−import Data.Coerce
33−
34−-- | The parametrizable state monad.
35−--
36−-- Computations have access to a mutable state.
37−--
38−-- The 'return' function leaves the state unchanged, while '>>=' uses
39−-- the final state of the first computation as the initial state of the second.
40−type State tag r = StateT tag r Identity
41−
42−-- | The state monad transformer.
43−--
44−-- The 'return' function leaves the state unchanged, while '>>=' uses
45−-- the final state of the first computation as the initial state of the second.
46−type StateT tag s = D.Handler (TAGGED STATE tag) (T.StateT s)
47−
48−-- | Constructor for computations in the state monad transformer.
49−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
50−stateT = coerce (T.StateT @s @m @a)
51−{-# INLINE stateT #-}
52−
53−-- | Runs a 'StateT' with the given initial state
54−-- and returns both the final value and the final state.
55−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
56−runStateT = coerce (T.runStateT @s @m @a)
57−{-# INLINE runStateT #-}
58−
59−-- | Runs a 'StateT' with the given initial state
60−-- and returns the final value, discarding the final state.
61−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
62−evalStateT = coerce (T.evalStateT @m @s @a)
63−{-# INLINE evalStateT #-}
64−
65−-- | Runs a 'StateT' with the given initial state
66−-- and returns the final state, discarding the final value.
67−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
68−execStateT = coerce (T.execStateT @m @s @a)
69−{-# INLINE execStateT #-}
70−
71−-- | Runs a 'State' with the given initial state
72−-- and returns both the final value and the final state.
73−runState :: forall tag s a . State tag s a -> s -> (a, s)
74−runState = coerce (T.runState @s @a)
75−{-# INLINE runState #-}
76−
77−-- | Runs a 'State' with the given initial state
78−-- and returns the final value, discarding the final state.
79−evalState :: forall tag s a . State tag s a -> s -> a
80−evalState = coerce (T.evalState @s @a)
81−{-# INLINE evalState #-}
82−
83−-- | Runs a 'State' with the given initial state
84−-- and returns the final state, discarding the final value.
85−execState :: forall tag s a . State tag s a -> s -> s
86−execState = coerce (T.execState @s @a)
87−{-# INLINE execState #-}
ether/src/Control/Monad/Ether/State/Strict.hsdeleted−87
@@ -1,87 +0,0 @@
1−-- | See "Control.Monad.State.Strict".
2−
3−module Control.Monad.Ether.State.Strict
4− (
5− -- * MonadState class
6− MonadState
7− , get
8− , put
9− , state
10− , modify
11− , gets
12− -- * The State monad
13− , State
14− , runState
15− , evalState
16− , execState
17− -- * The StateT monad transformer
18− , StateT
19− , stateT
20− , runStateT
21− , evalStateT
22− , execStateT
23− -- *
24− , STATE
25− ) where
26−
27−import Control.Monad.Ether.Handle
28−import Control.Monad.Ether.State.Common
29−import qualified Control.Monad.Trans.Ether.Handler as D
30−import qualified Control.Monad.Trans.State.Strict as T
31−import Data.Functor.Identity
32−import Data.Coerce
33−
34−-- | The parametrizable state monad.
35−--
36−-- Computations have access to a mutable state.
37−--
38−-- The 'return' function leaves the state unchanged, while '>>=' uses
39−-- the final state of the first computation as the initial state of the second.
40−type State tag r = StateT tag r Identity
41−
42−-- | The state monad transformer.
43−--
44−-- The 'return' function leaves the state unchanged, while '>>=' uses
45−-- the final state of the first computation as the initial state of the second.
46−type StateT tag s = D.Handler (TAGGED STATE tag) (T.StateT s)
47−
48−-- | Constructor for computations in the state monad transformer.
49−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
50−stateT = coerce (T.StateT @s @m @a)
51−{-# INLINE stateT #-}
52−
53−-- | Runs a 'StateT' with the given initial state
54−-- and returns both the final value and the final state.
55−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
56−runStateT = coerce (T.runStateT @s @m @a)
57−{-# INLINE runStateT #-}
58−
59−-- | Runs a 'StateT' with the given initial state
60−-- and returns the final value, discarding the final state.
61−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
62−evalStateT = coerce (T.evalStateT @m @s @a)
63−{-# INLINE evalStateT #-}
64−
65−-- | Runs a 'StateT' with the given initial state
66−-- and returns the final state, discarding the final value.
67−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
68−execStateT = coerce (T.execStateT @m @s @a)
69−{-# INLINE execStateT #-}
70−
71−-- | Runs a 'State' with the given initial state
72−-- and returns both the final value and the final state.
73−runState :: forall tag s a . State tag s a -> s -> (a, s)
74−runState = coerce (T.runState @s @a)
75−{-# INLINE runState #-}
76−
77−-- | Runs a 'State' with the given initial state
78−-- and returns the final value, discarding the final state.
79−evalState :: forall tag s a . State tag s a -> s -> a
80−evalState = coerce (T.evalState @s @a)
81−{-# INLINE evalState #-}
82−
83−-- | Runs a 'State' with the given initial state
84−-- and returns the final state, discarding the final value.
85−execState :: forall tag s a . State tag s a -> s -> s
86−execState = coerce (T.execState @s @a)
87−{-# INLINE execState #-}
ether/src/Control/Monad/Ether/State/Zoom.hsdeleted−47
@@ -1,47 +0,0 @@
1−{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
2−
3−module Control.Monad.Ether.State.Zoom
4− ( TAG_ZOOM
5− , TagZoomT
6− , tagZoom
7− ) where
8−
9−import Control.Ether.Optic
10−import Data.Kind as K
11−import Data.Reflection
12−import Control.Monad.Trans.Ether.Handler
13−import Control.Monad.Trans.Identity
14−import Control.Monad.Ether.State.Class
15−import Data.Proxy
16−import Data.Coerce
17−
18−-- | Encode type-level information for 'tagZoom'.
19−data TAG_ZOOM t z
20−
21−type TagZoomT t (z :: K.Type) = Handler (TAG_ZOOM t z) IdentityT
22−
23−newtype ReifiedLens s t a b = Lens { runLens :: 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)
ether/src/Control/Monad/Ether/TagAttach.hsdeleted−66
@@ -1,66 +0,0 @@
1−module Control.Monad.Ether.TagAttach
2− ( TAG_ATTACH
3− , TagAttachT
4− , tagAttach
5− ) where
6−
7−import Control.Monad.Trans.Identity
8−
9−import Control.Monad.Ether.Reader.Class
10−import Control.Monad.Ether.State.Class
11−import Control.Monad.Ether.Except.Class
12−import Control.Monad.Ether.Writer.Class
13−
14−import Control.Monad.Ether.Reader as A
15−import Control.Monad.Ether.State.Common as A
16−import Control.Monad.Ether.Except as A
17−import Control.Monad.Ether.Writer as A
18−
19−import qualified Control.Monad.Reader.Class as Class
20−import qualified Control.Monad.State.Class as Class
21−import qualified Control.Monad.Writer.Class as Class
22−import qualified Control.Monad.Error.Class as Class
23−
24−import Control.Monad.Trans.Ether.Handler
25−
26−import Data.Coerce
27−
28−-- | Encode type-level information for 'tagAttach'.
29−data TAG_ATTACH t
30−
31−type TagAttachT t = Handler (TAG_ATTACH t) IdentityT
32−
33−-- | Attach a tag to untagged transformers.
34−tagAttach :: forall tag m a . TagAttachT tag m a -> m a
35−tagAttach = coerce (runIdentityT @_ @m @a)
36−{-# INLINE tagAttach #-}
37−
38−instance
39− ( MonadReader tag r m, trans ~ IdentityT
40− ) => Class.MonadReader r (Handler (TAG_ATTACH tag) trans m)
41− where
42− ask = A.ask @tag
43− local = A.local @tag
44−
45−instance
46− ( MonadState tag s m, trans ~ IdentityT
47− ) => Class.MonadState s (Handler (TAG_ATTACH tag) trans m)
48− where
49− get = A.get @tag
50− put = A.put @tag
51−
52−instance
53− ( MonadExcept tag e m, trans ~ IdentityT
54− ) => Class.MonadError e (Handler (TAG_ATTACH tag) trans m)
55− where
56− throwError = A.throw @tag
57− catchError = A.catch @tag
58−
59−instance
60− ( MonadWriter tag w m, trans ~ IdentityT
61− ) => Class.MonadWriter w (Handler (TAG_ATTACH tag) trans m)
62− where
63− writer = A.writer @tag
64− tell = A.tell @tag
65− listen = A.listen @tag
66− pass = A.pass @tag
ether/src/Control/Monad/Ether/TagReplace.hsdeleted−61
@@ -1,61 +0,0 @@
1−module Control.Monad.Ether.TagReplace
2− ( TAG_REPLACE
3− , TagReplaceT
4− , tagReplace
5− ) where
6−
7−import Control.Monad.Trans.Identity
8−
9−import Control.Monad.Ether.Reader.Class
10−import Control.Monad.Ether.State.Class
11−import Control.Monad.Ether.Except.Class
12−import Control.Monad.Ether.Writer.Class
13−
14−import Control.Monad.Ether.Reader as A
15−import Control.Monad.Ether.State.Common as A
16−import Control.Monad.Ether.Except as A
17−import Control.Monad.Ether.Writer as A
18−
19−import Control.Monad.Trans.Ether.Handler
20−
21−import Data.Coerce
22−
23−-- | Encode type-level information for 'tagReplace'.
24−data TAG_REPLACE tOld tNew
25−
26−type TagReplaceT tOld tNew = Handler (TAG_REPLACE tOld tNew) IdentityT
27−
28−-- | Replace a tag with another tag.
29−tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
30−tagReplace = coerce (runIdentityT @_ @m @a)
31−{-# INLINE tagReplace #-}
32−
33−instance
34− ( MonadReader tNew r m, trans ~ IdentityT
35− ) => MonadReader tOld r (Handler (TAG_REPLACE tOld tNew) trans m)
36− where
37− ask = A.ask @tNew
38− local = A.local @tNew
39−
40−instance
41− ( MonadState tNew s m, trans ~ IdentityT
42− ) => MonadState tOld s (Handler (TAG_REPLACE tOld tNew) trans m)
43− where
44− get = A.get @tNew
45− put = A.put @tNew
46−
47−instance
48− ( MonadExcept tNew e m, trans ~ IdentityT
49− ) => MonadExcept tOld e (Handler (TAG_REPLACE tOld tNew) trans m)
50− where
51− throw = A.throw @tNew
52− catch = A.catch @tNew
53−
54−instance
55− ( MonadWriter tNew w m, trans ~ IdentityT
56− ) => MonadWriter tOld w (Handler (TAG_REPLACE tOld tNew) trans m)
57− where
58− writer = A.writer @tNew
59− tell = A.tell @tNew
60− listen = A.listen @tNew
61− pass = A.pass @tNew
ether/src/Control/Monad/Ether/Writer.hsdeleted−121
@@ -1,121 +0,0 @@
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 #-}
ether/src/Control/Monad/Ether/Writer/Class.hsdeleted−49
@@ -1,49 +0,0 @@
1−-- | See "Control.Monad.Writer.Class".
2−
3−module Control.Monad.Ether.Writer.Class
4− ( MonadWriter(..)
5− ) where
6−
7−import qualified Control.Monad.Trans.Lift.Listen as Lift
8−import qualified Control.Monad.Trans.Lift.Pass as Lift
9−
10−-- | See 'Control.Monad.Writer.MonadWriter'.
11−class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
12−
13− {-# MINIMAL (writer | tell), listen, pass #-}
14−
15− -- | Embed a simple writer action.
16− writer :: (a, w) -> m a
17− writer ~(a, w) = a <$ tell @tag w
18−
19− -- | Append a value to the accumulator within the monad.
20− tell :: w -> m ()
21− tell w = writer @tag ((),w)
22−
23− -- | Execute an action and add its accumulator
24− -- to the value of the computation.
25− listen :: m a -> m (a, w)
26−
27− -- | Execute an action which returns a value and a function,
28− -- and return the value, applying the function to the accumulator.
29− pass :: m (a, w -> w) -> m a
30−
31−instance {-# OVERLAPPABLE #-}
32− ( Lift.LiftListen t
33− , Lift.LiftPass t
34− , Monad (t m)
35− , MonadWriter tag w m
36− , Monoid w
37− ) => MonadWriter tag w (t m) where
38−
39− writer = Lift.lift . writer @tag
40− {-# INLINE writer #-}
41−
42− tell = Lift.lift . tell @tag
43− {-# INLINE tell #-}
44−
45− listen = Lift.liftListen (listen @tag)
46− {-# INLINE listen #-}
47−
48− pass = Lift.liftPass (pass @tag)
49− {-# INLINE pass #-}
ether/src/Control/Monad/Trans/Ether/Handler.hsdeleted−177
@@ -1,177 +0,0 @@
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
shell.nixnew file+22
@@ -0,0 +1,22 @@
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/Ether.hsnew file+25
@@ -0,0 +1,25 @@
1+module Ether
2+ ( module Control.Monad
3+ , module Control.Monad.Fix
4+ , module Control.Monad.Trans.Identity
5+ , module Data.Functor.Identity
6+ , module Data.Tagged
7+ , module Ether.Reader
8+ , module Ether.Writer
9+ , module Ether.State
10+ , module Ether.Except
11+ , module Ether.TagDispatch
12+ , module Ether.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.hsnew file+127
@@ -0,0 +1,127 @@
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.hsnew file+68
@@ -0,0 +1,68 @@
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.hsnew file+24
@@ -0,0 +1,24 @@
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.hsnew file+79
@@ -0,0 +1,79 @@
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.hsnew file+14
@@ -0,0 +1,14 @@
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.hsnew file+18
@@ -0,0 +1,18 @@
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.hsnew file+24
@@ -0,0 +1,24 @@
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.hsnew file+236
@@ -0,0 +1,236 @@
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.hsnew file+415
@@ -0,0 +1,415 @@
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.hsnew file+138
@@ -0,0 +1,138 @@
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.hsnew file+206
@@ -0,0 +1,206 @@
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.hsnew file+287
@@ -0,0 +1,287 @@
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.yamldeleted−5
@@ -1,5 +0,0 @@
1−resolver: lts-8.12
2−
3−packages:
4−- 'ether'
5−- 'ether-suite'
ether-suite/test/Regression.hs → test/Regression.hsrenamed

The content is the same.

ether-suite/test/Regression/T1.hs → test/Regression/T1.hsrenamed+16−5
@@ -1,7 +1,8 @@
11module Regression.T1 (test1) where
22
3−import Control.Monad.Ether
4−import Control.Ether.Abbr
3+import Ether
4+import TupleInstances ()
5+import Data.List (group)
56
67import Test.Tasty
78import Test.Tasty.QuickCheck
@@ -10,7 +11,7 @@ data Tag1
1011data Tag2
1112
1213testEther
13− :: Ether '[Tag1 --> String, Tag2 --> String] m
14+ :: (MonadReader Tag1 String m, MonadReader Tag2 String m)
1415 => m ((String, String), (String, String))
1516testEther = do
1617 s1 <- ask @Tag1
@@ -24,6 +25,10 @@ testEther = do
2425
2526runner1 s1 s2 = flip (runReader @Tag1) s1 . flip (runReaderT @Tag2) s2
2627runner2 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
2732
2833test1 :: TestTree
2934test1 = testGroup "T1: Reader local environment"
@@ -33,7 +38,13 @@ test1 = testGroup "T1: Reader local environment"
3338 , testProperty "runner₂ works"
3439 $ \s1 s2 -> property
3540 $ runner2 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
36− , testProperty "runner₁ == runner₂"
41+ , testProperty "runner₃ works"
42+ $ \s1 s2 -> property
43+ $ runner3 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
44+ , testProperty "runner₁ == runner₂ == runner₃"
3745 $ \s1 s2 -> property
38− $ runner1 s1 s2 testEther == runner2 s1 s2 testEther
46+ $ same
47+ [ runner1 s1 s2 testEther
48+ , runner2 s1 s2 testEther
49+ , runner3 s1 s2 testEther ]
3950 ]
ether-suite/test/Regression/T10.hs → test/Regression/T10.hsrenamed+11−10
@@ -2,22 +2,23 @@ module Regression.T10 (test10) where
22
33import Control.Applicative
44import Data.Functor.Identity
5−import qualified Control.Monad.Ether.Implicit as I
5+
6+import Ether
67
78import Test.Tasty
89import Test.Tasty.QuickCheck
910
10−testEther :: Integer -> I.StateT Integer Maybe [Integer]
11+testEther :: Integer -> StateT' Integer Maybe [Integer]
1112testEther m = range
1213 where
1314 range = liftA2 (:) yield (range <|> pure [])
14− yield = I.stateT $ \n -> do
15− I.guard (n <= m)
15+ yield = stateT' $ \n -> do
16+ guard (n <= m)
1617 Just (n, n + 1)
1718
18−testEther' :: Integer -> I.State Integer [Integer]
19+testEther' :: Integer -> State' Integer [Integer]
1920testEther' m =
20− I.stateT $ Identity . maybe ([], m + 1) id . I.runStateT (testEther m)
21+ stateT' $ Identity . maybe ([], m + 1) id . runStateT' (testEther m)
2122
2223next1 :: Integer -> Integer -> Maybe Integer
2324next1 m n
@@ -32,11 +33,11 @@ range1 m n
3233test10 :: TestTree
3334test10 = testGroup "T10: Alternative instance"
3435 [ testProperty "execStateT works"
35− $ \m n -> I.execStateT (testEther m) n == next1 m n
36+ $ \m n -> execStateT' (testEther m) n == next1 m n
3637 , testProperty "evalStateT works"
37− $ \m n -> I.evalStateT (testEther m) n == range1 m n
38+ $ \m n -> evalStateT' (testEther m) n == range1 m n
3839 , testProperty "execState works"
39− $ \m n -> I.execState (testEther' m) n == m + 1
40+ $ \m n -> execState' (testEther' m) n == m + 1
4041 , testProperty "evalState works"
41− $ \m n -> I.evalState (testEther' m) n == [n..m]
42+ $ \m n -> evalState' (testEther' m) n == [n..m]
4243 ]
ether-suite/test/Regression/T11.hs → test/Regression/T11.hsrenamed+4−4
@@ -1,8 +1,8 @@
11module Regression.T11 (test11) where
22
3−import Data.Bool
4−import Control.Monad.Ether
3+import Ether
54
5+import Data.Bool
66import qualified Control.Monad.State as T
77import qualified Control.Monad.Reader as T
88
@@ -28,12 +28,12 @@ model n = zipWith ($) (cycle [id, negate]) [n..]
2828
2929runner1 n
3030 = flip (T.runReader) n
31− . flip (execStateT @STag) []
31+ . flip (execLazyStateT @STag) []
3232 . flip T.evalStateT False
3333
3434runner2 n
3535 = flip T.evalState False
36− . flip (execStateT @STag) []
36+ . flip (execLazyStateT @STag) []
3737 . flip T.runReaderT n
3838
3939test11 :: TestTree
ether-suite/test/Regression/T12.hs → test/Regression/T12.hsrenamed+3−4
@@ -1,7 +1,6 @@
11module Regression.T12 (test12) where
22
3−import Control.Monad.Ether.State
4−import Control.Monad.Ether.State.Zoom
3+import Ether
54import Control.Lens
65
76import Test.Tasty
@@ -14,8 +13,8 @@ succState = modify @Foo succ
1413
1514testEther :: (Enum a, MonadState Foo (a, a) m) => m (a, a)
1615testEther = do
17− tagZoom @Foo _1 succState
18− tagZoom @Foo _2 $ modify @Foo pred
16+ Ether.zoom @Foo _1 succState
17+ Ether.zoom @Foo _2 $ modify @Foo pred
1918 get @Foo
2019
2120model :: Enum a => (a, a) -> (a, a)
ether-suite/test/Regression/T2.hs → test/Regression/T2.hsrenamed+7−9
@@ -1,20 +1,18 @@
11module Regression.T2 (test2) where
22
3−import Control.Ether.Abbr
4−import qualified Control.Monad.Ether.Implicit as I
5−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
64
75import Test.Tasty
86import Test.Tasty.QuickCheck
97
10−testEther :: Ether '[I.R Integer, I.R Bool] m => m String
11−testEther = I.local (succ :: Integer -> Integer) $ do
12− n :: Integer <- I.asks (*2)
13− b <- I.local not I.ask
8+testEther :: (MonadReader' Integer m, MonadReader' Bool m) => m String
9+testEther = local' (succ :: Integer -> Integer) $ do
10+ n :: Integer <- asks' (*2)
11+ b <- local' not ask'
1412 return (if b then "" else show n)
1513
16−runner1 (n :: Integer) = flip I.runReader n . flip I.runReaderT True
17−runner2 (n :: Integer) = flip I.runReader True . flip I.runReaderT n
14+runner1 (n :: Integer) = flip runReader' n . flip runReaderT' True
15+runner2 (n :: Integer) = flip runReader' True . flip runReaderT' n
1816
1917test2 :: TestTree
2018test2 = testGroup "T2: Implicit tags"
ether-suite/test/Regression/T3.hs → test/Regression/T3.hsrenamed+2−3
@@ -1,7 +1,6 @@
11module Regression.T3 (test3) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.Reader as T
76import qualified Control.Monad.State as T
@@ -20,7 +19,7 @@ testMTL = do
2019 return (a * b)
2120
2221testEther
23− :: Ether '[STag --> Int, STag <-> Int, RTag --> Int] m
22+ :: (MonadReader STag Int m, MonadState STag Int m, MonadReader RTag Int m)
2423 => m (Int, Int, Int)
2524testEther = local @RTag (*2) $ do
2625 a_mul_b <- tagAttach @STag testMTL
ether-suite/test/Regression/T4.hs → test/Regression/T4.hsrenamed+2−3
@@ -1,14 +1,13 @@
11module Regression.T4 (test4) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
87
98data RTag
109
11−testEther :: Ether '[RTag --> Int] m => m Int
10+testEther :: MonadReader RTag Int m => m Int
1211testEther = ask @RTag
1312
1413runner r
ether-suite/test/Regression/T5.hs → test/Regression/T5.hsrenamed+8−11
@@ -1,9 +1,6 @@
11module Regression.T5 (test5) where
22
3−import Control.Ether.Abbr
4−
5−import qualified Control.Monad.Ether.Implicit as I
6−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
74
85import Test.Tasty
96import Test.Tasty.QuickCheck
@@ -16,22 +13,22 @@ incCounter = succ
1613
1714testEther
1815 :: (Num a, Ord a)
19− => Ether '[I.R a, I.S Counter] m
16+ => (MonadReader' a m, MonadState' Counter m)
2017 => m a
2118testEther = do
22− a <- I.ask
19+ a <- ask'
2320 if a <= 0
2421 then do
25− I.put (0 :: Counter)
22+ put' (0 :: Counter)
2623 return 1
2724 else do
28− I.modify incCounter -- overriden in the base case
29− b <- I.runReaderT testEther (a - 1)
30− I.modify incCounter
25+ modify' incCounter -- overriden in the base case
26+ b <- runReaderT' testEther (a - 1)
27+ modify' incCounter
3128 return (a * b)
3229
3330runner :: (Num a, Ord a) => a -> (a, Counter)
34−runner a = I.runState (I.runReaderT testEther a) (0 :: Counter)
31+runner a = runState' (runReaderT' testEther a) (0 :: Counter)
3532
3633factorial :: (Num a, Enum a) => a -> a
3734factorial a = product [1..a]
ether-suite/test/Regression/T6.hs → test/Regression/T6.hsrenamed+14−16
@@ -1,10 +1,7 @@
11module Regression.T6 (test6) where
22
3−import Control.Monad
4−import Control.Ether.Abbr
5−
6−import qualified Control.Monad.Ether.Implicit as I
7−import qualified Control.Ether.Implicit.Abbr as I
3+import Data.Function
4+import Ether
85
96import Test.Tasty
107import Test.Tasty.QuickCheck
@@ -17,32 +14,33 @@ data NegativeLog a = NegativeLog a
1714
1815testEther
1916 :: (Floating a, Ord a)
20− => Ether '[I.E DivideByZero, I.E (NegativeLog a)] m
17+ => (MonadExcept' DivideByZero m, MonadExcept' (NegativeLog a) m)
2118 => a -> a -> m a
2219testEther a b = do
23− when (b == 0) (I.throw DivideByZero)
20+ when (b == 0) (throw' DivideByZero)
2421 let d = a / b
25− when (d < 0) (I.throw (NegativeLog d))
22+ when (d < 0) (throw' (NegativeLog d))
2623 return (log d)
2724
28−-- Copied verbatim from "Data.Function" to support @base < 4.8@.
29−(&) :: a -> (a -> b) -> b
30−x & f = f x
31−
3225handleNegativeLog (NegativeLog (x :: Double)) = "nl: " ++ show x
3326handleDivideByZero DivideByZero = "dz"
3427
28+handleT' :: Functor m => (e -> a) -> ExceptT' e m a -> m a
29+handleT' h m = fmap (either h id) (runExceptT' m)
30+
3531runner1 :: Double -> Double -> String
3632runner1 a b = do
3733 (show `fmap` testEther a b)
38− & I.handleT handleNegativeLog
39− & I.handle handleDivideByZero
34+ & handleT' handleNegativeLog
35+ & handleT' handleDivideByZero
36+ & runIdentity
4037
4138runner2 :: Double -> Double -> String
4239runner2 a b = do
4340 (show `fmap` testEther a b)
44− & I.handleT handleDivideByZero
45− & I.handle handleNegativeLog
41+ & handleT' handleDivideByZero
42+ & handleT' handleNegativeLog
43+ & runIdentity
4644
4745logDiv :: Double -> Double -> String
4846logDiv a b
ether-suite/test/Regression/T7.hs → test/Regression/T7.hsrenamed+1−1
@@ -3,7 +3,7 @@ module Regression.T7 (test7) where
33import Data.Monoid
44import Control.Monad
55
6−import Control.Monad.Ether
6+import Ether
77import qualified Control.Monad.Writer as T
88
99import Test.Tasty
ether-suite/test/Regression/T8.hs → test/Regression/T8.hsrenamed+2−3
@@ -1,7 +1,6 @@
11module Regression.T8 (test8) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.State as T
76
@@ -18,7 +17,7 @@ testMTL2 :: T.MonadState Bool m => m ()
1817testMTL2 = T.modify not
1918
2019testEther
21− :: Ether '[Foo <-> Int, Bar <-> Bool] m
20+ :: (MonadState Foo Int m, MonadState Bar Bool m)
2221 => m String
2322testEther = do
2423 tagAttach @Foo testMTL1
ether-suite/test/Regression/T9.hs → test/Regression/T9.hsrenamed+4−5
@@ -1,7 +1,6 @@
11module Regression.T9 (test9) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
@@ -9,16 +8,16 @@ import Test.Tasty.QuickCheck
98data Foo
109data Bar
1110
12−testEther1 :: Ether '[Foo <-> Int] m => m String
11+testEther1 :: MonadState Foo Int m => m String
1312testEther1 = do
1413 modify @Foo negate
1514 gets @Foo show
1615
17−testEther2 :: Ether '[Bar <-> Int] m => m String
16+testEther2 :: MonadState Bar Int m => m String
1817testEther2 = tagReplace @Foo @Bar testEther1
1918
2019testEther
21− :: Ether '[Foo <-> Int, Bar <-> Int] m
20+ :: (MonadState Foo Int m, MonadState Bar Int m)
2221 => m String
2322testEther = do
2423 a <- testEther1
test/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
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