on 9de2a97 help sign in
77 files changed+2477−2167
since splitsnapshots
unifiedsplit
.gitignore+2−18 .travis.yml+18−25 README.md+16 bench/TupleInstances.hs−9 ether-flatten/CHANGELOG.md LICENSE → ether-flatten/LICENSE Setup.hs → ether-flatten/Setup.hs ether-flatten/ether-flatten.cabal+45 ether-flatten/src/Control/Ether/Flatten.hs+237 ether-flatten/src/Control/Monad/Ether/Reader/Flatten.hs+63 ether-flatten/src/Control/Monad/Ether/State/Flatten.hs+70 ether-suite/Setup.hs+2 bench/Bench.hs → ether-suite/bench/Bench.hs+78−95 ether-suite/ether-suite.cabal+71 test/Regression.hs → ether-suite/test/Regression.hs test/Regression/T1.hs → ether-suite/test/Regression/T1.hs+5−16 test/Regression/T10.hs → ether-suite/test/Regression/T10.hs+10−11 test/Regression/T11.hs → ether-suite/test/Regression/T11.hs+4−4 test/Regression/T12.hs → ether-suite/test/Regression/T12.hs+4−3 test/Regression/T2.hs → ether-suite/test/Regression/T2.hs+9−7 test/Regression/T3.hs → ether-suite/test/Regression/T3.hs+3−2 test/Regression/T4.hs → ether-suite/test/Regression/T4.hs+3−2 test/Regression/T5.hs → ether-suite/test/Regression/T5.hs+11−8 test/Regression/T6.hs → ether-suite/test/Regression/T6.hs+16−14 test/Regression/T7.hs → ether-suite/test/Regression/T7.hs+1−1 test/Regression/T8.hs → ether-suite/test/Regression/T8.hs+3−2 test/Regression/T9.hs → ether-suite/test/Regression/T9.hs+5−4 ether-zoom/CHANGELOG.md ether-zoom/LICENSE+30 ether-zoom/Setup.hs+2 ether-zoom/ether-zoom.cabal+40 ether-zoom/src/Control/Monad/Ether/State/Zoom.hs+50 ether.cabal−237 CHANGELOG.md → ether/CHANGELOG.md+3−17 ether/LICENSE+30 ether/Setup.hs+2 ether/ether.cabal+81 ether/src/Control/Ether/Abbr.hs+60 ether/src/Control/Ether/Implicit/Abbr.hs+25 ether/src/Control/Monad/Ether.hs+13 ether/src/Control/Monad/Ether/Except.hs+83 ether/src/Control/Monad/Ether/Except/Class.hs+30 ether/src/Control/Monad/Ether/Implicit.hs+13 ether/src/Control/Monad/Ether/Implicit/Except.hs+60 ether/src/Control/Monad/Ether/Implicit/Reader.hs+59 ether/src/Control/Monad/Ether/Implicit/State.hs+7 ether/src/Control/Monad/Ether/Implicit/State/Lazy.hs+84 ether/src/Control/Monad/Ether/Implicit/State/Strict.hs+84 ether/src/Control/Monad/Ether/Implicit/Writer.hs+79 ether/src/Control/Monad/Ether/Reader.hs+96 ether/src/Control/Monad/Ether/Reader/Class.hs+69 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+48 ether/src/Control/Monad/Ether/State/Lazy.hs+89 ether/src/Control/Monad/Ether/State/Strict.hs+89 ether/src/Control/Monad/Ether/TagAttach.hs+73 ether/src/Control/Monad/Ether/TagReplace.hs+68 ether/src/Control/Monad/Ether/Writer.hs+112 ether/src/Control/Monad/Ether/Writer/Class.hs+48 ether/src/Control/Monad/Trans/Ether/Handler.hs+186 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+7 test/TupleInstances.hs−9
.gitignore+2−18
@@ -1,21 +1,5 @@
1−# Cabal
1+tags
22dist
3−dist-newstyle
3+.stack-work
44.cabal-sandbox/
55cabal.sandbox.config
6−cabal.project.local
7−.ghc.environment*
8−
9−# Profiling
10−*.prof
11−
12−# Stack
13−.stack-work
14−
15−# Emacs
16−TAGS
17−.dir-locals.el
18−
19−# Vim
20−tags
21−*.swp
.travis.yml+18−25
@@ -1,31 +1,24 @@
1−language: nix
1+sudo: false
22
3−os:
4− - linux
5− - osx
6−
7−env:
8− - HC=ghc822
9− - HC=ghc844
10− - HC=ghc861
3+cache:
4+ directories:
5+ - $HOME/.stack/
116
127before_install:
13− - curl https://raw.githubusercontent.com/monadfix/nix-cabal/master/nix-cabal -o nix-cabal && chmod u+x nix-cabal
14− - travis_retry ./nix-cabal new-update
8+ - mkdir -p ~/.local/bin
9+ - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
10+ - export PATH=~/.local/bin:$PATH
11+ - stack --version
12+ - stack setup
1513
16−script:
17− - ./nix-cabal new-test ether:regression
18− - ./nix-cabal new-bench ether:bench
14+install:
15+ - stack install --only-dependencies --no-terminal
1916
20−cache:
21− directories:
22− - ~/.cabal
23− - ~/.ghc
17+script:
18+ - stack test ether-suite:regression --no-terminal --ghc-options -Werror
19+ - stack bench ether-suite:bench --no-terminal --ghc-options -Werror
2420
25−matrix:
26− # broken at the moment
27− exclude:
28− - os: osx
29− env: HC=ghc822
30− - os: osx
31− env: HC=ghc861
21+addons:
22+ apt:
23+ packages:
24+ - libgmp-dev
README.md+16
@@ -2,8 +2,24 @@
22
33[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
44[![Hackage](https://img.shields.io/hackage/v/ether.svg)](https://hackage.haskell.org/package/ether)
5+[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/int-index/ether)
56
67
78Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
89and [transformers](https://hackage.haskell.org/package/transformers) with tagged
910monad transformers and classes in a compatible way.
11+
12+## Installation
13+
14+You can install `ether 0.4.0.0`
15+
16+1. using Cabal, from Hackage;
17+2. using Stack, from Stackage;
18+3. using Portage, from Gentoo Haskell Overlay.
19+
20+If unsure, use [Stack](https://github.com/commercialhaskell/stack).
21+
22+## Getting Started
23+
24+To get started, read the introduction on the [homepage](https://int-index.github.io/ether/).
25+If you need help with Ether or if you have any questions about it, ask me in the Gitter chat.
bench/TupleInstances.hsdeleted−9
@@ -1,9 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module TupleInstances () where
5−
6−#ifdef DISABLE_TUP_INSTANCES
7−import Ether.Internal (makeTupleInstancesHasLens)
8−makeTupleInstancesHasLens [4,5,9]
9−#endif
ether-flatten/CHANGELOG.mdnew file

No changes to the content.

LICENSE → ether-flatten/LICENSErenamed

The content is the same.

Setup.hs → ether-flatten/Setup.hsrenamed

The content is the same.

ether-flatten/ether-flatten.cabalnew file+45
@@ -0,0 +1,45 @@
1+name: ether-flatten
2+version: 0.1.0.0
3+synopsis: Flatten nested monad transformers
4+description:
5+ Flatten nested monad transformers to gain performance.
6+
7+category: Control
8+license: BSD3
9+license-file: LICENSE
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+cabal-version: >=1.18
16+extra-source-files: CHANGELOG.md
17+
18+source-repository head
19+
20+ type: git
21+ location: git@github.com:int-index/ether.git
22+
23+
24+library
25+
26+ exposed-modules: Control.Monad.Ether.Reader.Flatten
27+ , Control.Monad.Ether.State.Flatten
28+ , Control.Ether.Flatten
29+ build-depends: base >=4.9 && <4.10
30+ , ether >=0.5 && <0.6
31+ , mtl >=2.2.1
32+ , transformers >=0.4.2
33+ , transformers-lift >=0.1.0.1
34+ , ghc-prim >=0.3
35+ , lens >=4.14
36+ , deepseq >= 1.4
37+
38+ default-language: Haskell2010
39+ default-extensions: PolyKinds
40+ ScopedTypeVariables
41+ FunctionalDependencies
42+ TypeApplications
43+
44+ hs-source-dirs: src
45+ ghc-options: -Wall -O2
ether-flatten/src/Control/Ether/Flatten.hsnew file+237
@@ -0,0 +1,237 @@
1+{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE TypeSynonymInstances #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+{-# LANGUAGE TemplateHaskell #-}
10+{-# LANGUAGE StandaloneDeriving #-}
11+{-# LANGUAGE AllowAmbiguousTypes #-}
12+{-# LANGUAGE DeriveGeneric #-}
13+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
14+
15+module Control.Ether.Flatten
16+ ( HasLens(..)
17+ , Product(..)
18+ ) where
19+
20+import Control.DeepSeq
21+import Control.Lens
22+import GHC.Generics (Generic)
23+
24+class HasLens tag outer inner | tag outer -> inner where
25+ lensOf :: Lens' outer inner
26+
27+data family Product :: [k] -> [*] -> *
28+
29+data instance Product ts '[a1, a2, a3, a4] =
30+ P4
31+ { p4_1 :: !a1
32+ , p4_2 :: !a2
33+ , p4_3 :: !a3
34+ , p4_4 :: !a4
35+ } deriving (Generic)
36+
37+deriving instance
38+ ( Show a1
39+ , Show a2
40+ , Show a3
41+ , Show a4
42+ ) => Show (Product ts '[a1, a2, a3, a4])
43+
44+instance
45+ ( NFData a1
46+ , NFData a2
47+ , NFData a3
48+ , NFData a4
49+ ) => NFData (Product ts '[a1, a2, a3, a4])
50+
51+instance a ~ a1 => HasLens t1
52+ (Product
53+ '[t1, t2, t3, t4]
54+ '[a1, a2, a3, a4]) a where
55+ lensOf = lens p4_1 (\p a -> p{ p4_1 = a })
56+ {-# INLINE lensOf #-}
57+
58+instance a ~ a2 => HasLens t2
59+ (Product
60+ '[t1, t2, t3, t4]
61+ '[a1, a2, a3, a4]) a where
62+ lensOf = lens p4_2 (\p a -> p{ p4_2 = a })
63+ {-# INLINE lensOf #-}
64+
65+instance a ~ a3 => HasLens t3
66+ (Product
67+ '[t1, t2, t3, t4]
68+ '[a1, a2, a3, a4]) a where
69+ lensOf = lens p4_3 (\p a -> p{ p4_3 = a })
70+ {-# INLINE lensOf #-}
71+
72+instance a ~ a4 => HasLens t4
73+ (Product
74+ '[t1, t2, t3, t4]
75+ '[a1, a2, a3, a4]) a where
76+ lensOf = lens p4_4 (\p a -> p{ p4_4 = a })
77+ {-# INLINE lensOf #-}
78+
79+data instance Product ts '[a1, a2, a3, a4, a5] =
80+ P5
81+ { p5_1 :: !a1
82+ , p5_2 :: !a2
83+ , p5_3 :: !a3
84+ , p5_4 :: !a4
85+ , p5_5 :: !a5
86+ } deriving (Generic)
87+
88+deriving instance
89+ ( Show a1
90+ , Show a2
91+ , Show a3
92+ , Show a4
93+ , Show a5
94+ ) => Show (Product ts '[a1, a2, a3, a4, a5])
95+
96+instance
97+ ( NFData a1
98+ , NFData a2
99+ , NFData a3
100+ , NFData a4
101+ , NFData a5
102+ ) => NFData (Product ts '[a1, a2, a3, a4, a5])
103+
104+instance a ~ a1 => HasLens t1
105+ (Product
106+ '[t1, t2, t3, t4, t5]
107+ '[a1, a2, a3, a4, a5]) a where
108+ lensOf = lens p5_1 (\p a -> p{ p5_1 = a })
109+ {-# INLINE lensOf #-}
110+
111+instance a ~ a2 => HasLens t2
112+ (Product
113+ '[t1, t2, t3, t4, t5]
114+ '[a1, a2, a3, a4, a5]) a where
115+ lensOf = lens p5_2 (\p a -> p{ p5_2 = a })
116+ {-# INLINE lensOf #-}
117+
118+instance a ~ a3 => HasLens t3
119+ (Product
120+ '[t1, t2, t3, t4, t5]
121+ '[a1, a2, a3, a4, a5]) a where
122+ lensOf = lens p5_3 (\p a -> p{ p5_3 = a })
123+ {-# INLINE lensOf #-}
124+
125+instance a ~ a4 => HasLens t4
126+ (Product
127+ '[t1, t2, t3, t4, t5]
128+ '[a1, a2, a3, a4, a5]) a where
129+ lensOf = lens p5_4 (\p a -> p{ p5_4 = a })
130+ {-# INLINE lensOf #-}
131+
132+instance a ~ a5 => HasLens t5
133+ (Product
134+ '[t1, t2, t3, t4, t5]
135+ '[a1, a2, a3, a4, a5]) a where
136+ lensOf = lens p5_5 (\p a -> p{ p5_5 = a })
137+ {-# INLINE lensOf #-}
138+
139+data instance Product ts '[a1, a2, a3, a4, a5, a6, a7, a8, a9] =
140+ P9
141+ { p9_1 :: !a1
142+ , p9_2 :: !a2
143+ , p9_3 :: !a3
144+ , p9_4 :: !a4
145+ , p9_5 :: !a5
146+ , p9_6 :: !a6
147+ , p9_7 :: !a7
148+ , p9_8 :: !a8
149+ , p9_9 :: !a9
150+ } deriving (Generic)
151+
152+deriving instance
153+ ( Show a1
154+ , Show a2
155+ , Show a3
156+ , Show a4
157+ , Show a5
158+ , Show a6
159+ , Show a7
160+ , Show a8
161+ , Show a9
162+ ) => Show (Product ts '[a1, a2, a3, a4, a5, a6, a7, a8, a9])
163+
164+instance
165+ ( NFData a1
166+ , NFData a2
167+ , NFData a3
168+ , NFData a4
169+ , NFData a5
170+ , NFData a6
171+ , NFData a7
172+ , NFData a8
173+ , NFData a9
174+ ) => NFData (Product ts '[a1, a2, a3, a4, a5, a6, a7, a8, a9])
175+
176+instance a ~ a1 => HasLens t1
177+ (Product
178+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
179+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
180+ lensOf = lens p9_1 (\p a -> p{ p9_1 = a })
181+ {-# INLINE lensOf #-}
182+
183+instance a ~ a2 => HasLens t2
184+ (Product
185+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
186+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
187+ lensOf = lens p9_2 (\p a -> p{ p9_2 = a })
188+ {-# INLINE lensOf #-}
189+
190+instance a ~ a3 => HasLens t3
191+ (Product
192+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
193+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
194+ lensOf = lens p9_3 (\p a -> p{ p9_3 = a })
195+ {-# INLINE lensOf #-}
196+
197+instance a ~ a4 => HasLens t4
198+ (Product
199+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
200+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
201+ lensOf = lens p9_4 (\p a -> p{ p9_4 = a })
202+ {-# INLINE lensOf #-}
203+
204+instance a ~ a5 => HasLens t5
205+ (Product
206+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
207+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
208+ lensOf = lens p9_5 (\p a -> p{ p9_5 = a })
209+ {-# INLINE lensOf #-}
210+
211+instance a ~ a6 => HasLens t6
212+ (Product
213+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
214+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
215+ lensOf = lens p9_6 (\p a -> p{ p9_6 = a })
216+ {-# INLINE lensOf #-}
217+
218+instance a ~ a7 => HasLens t7
219+ (Product
220+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
221+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
222+ lensOf = lens p9_7 (\p a -> p{ p9_7 = a })
223+ {-# INLINE lensOf #-}
224+
225+instance a ~ a8 => HasLens t8
226+ (Product
227+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
228+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
229+ lensOf = lens p9_8 (\p a -> p{ p9_8 = a })
230+ {-# INLINE lensOf #-}
231+
232+instance a ~ a9 => HasLens t9
233+ (Product
234+ '[t1, t2, t3, t4, t5, t6, t7, t8, t9]
235+ '[a1, a2, a3, a4, a5, a6, a7, a8, a9]) a where
236+ lensOf = lens p9_9 (\p a -> p{ p9_9 = a })
237+ {-# INLINE lensOf #-}
ether-flatten/src/Control/Monad/Ether/Reader/Flatten.hsnew file+63
@@ -0,0 +1,63 @@
1+{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE TypeSynonymInstances #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+
10+module Control.Monad.Ether.Reader.Flatten
11+ ( runReader
12+ , runReaderT
13+ ) where
14+
15+import Data.Functor.Identity
16+import Control.Monad.Ether.Reader.Class as C
17+import Control.Monad.Trans.Ether.Handler
18+import qualified Control.Monad.Reader as T
19+import Control.Lens
20+import Control.Ether.Flatten
21+import Data.Coerce
22+
23+data READER
24+
25+type family READERS ts where
26+ READERS '[] = '[]
27+ READERS (t ': ts) = '(READER, t) ': READERS ts
28+
29+type ReaderT ts r = Handler (READERS ts) (T.ReaderT r)
30+
31+type Reader ts r = ReaderT ts r Identity
32+
33+instance
34+ ( HasLens tag payload r
35+ , T.MonadReader payload (trans m) -- FIXME: (forall m . T.MonadReader payload (trans m))
36+ ) => C.MonadReader tag r (Handler ('(READER, tag) ': dps) trans (m :: * -> *))
37+ where
38+
39+ ask =
40+ (coerce :: forall dp a .
41+ trans m a ->
42+ Handler dp trans m a)
43+ (view (lensOf @tag))
44+ {-# INLINE ask #-}
45+
46+ local f =
47+ (coerce :: forall dp a .
48+ (trans m a -> trans m a) ->
49+ (Handler dp trans m a -> Handler dp trans m a))
50+ (T.local (lensOf @tag %~ f))
51+ {-# INLINE local #-}
52+
53+runReaderT
54+ :: ReaderT tags (Product tags as) m a
55+ -> Product tags as
56+ -> m a
57+runReaderT m = T.runReaderT (coerce m)
58+
59+runReader
60+ :: Reader tags (Product tags as) a
61+ -> Product tags as
62+ -> a
63+runReader m = T.runReader (coerce m)
ether-flatten/src/Control/Monad/Ether/State/Flatten.hsnew file+70
@@ -0,0 +1,70 @@
1+{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE TypeSynonymInstances #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+
10+module Control.Monad.Ether.State.Flatten
11+ ( runState
12+ , runStateT
13+ ) where
14+
15+import Data.Functor.Identity
16+import Control.Monad.Ether.State.Class as C
17+import Control.Monad.Trans.Ether.Handler
18+import qualified Control.Monad.State as T
19+import Control.Lens
20+import Control.Ether.Flatten
21+import Data.Coerce
22+
23+data STATE
24+
25+type family STATES ts where
26+ STATES '[] = '[]
27+ STATES (t ': ts) = '(STATE, t) ': STATES ts
28+
29+type StateT ts s = Handler (STATES ts) (T.StateT s)
30+
31+type State ts s = StateT ts s Identity
32+
33+instance
34+ ( Monad m, HasLens tag payload s
35+ , T.MonadState payload (trans m) -- FIXME: (forall m . T.MonadState payload (trans m))
36+ ) => C.MonadState tag s (Handler ('(STATE, tag) ': dps) trans m)
37+ where
38+
39+ get =
40+ (coerce :: forall dp a .
41+ trans m a ->
42+ Handler dp trans m a)
43+ (use (lensOf @tag))
44+ {-# INLINE get #-}
45+
46+ put s =
47+ (coerce :: forall dp a .
48+ trans m a ->
49+ Handler dp trans m a)
50+ (T.modify (lensOf @tag .~ s))
51+ {-# INLINE put #-}
52+
53+ state f =
54+ (coerce :: forall dp a .
55+ trans m a ->
56+ Handler dp trans m a)
57+ (T.state (lensOf @tag f))
58+ {-# INLINE state #-}
59+
60+runStateT
61+ :: StateT tags (Product tags as) m a
62+ -> Product tags as
63+ -> m (a, Product tags as)
64+runStateT m = T.runStateT (coerce m)
65+
66+runState
67+ :: State tags (Product tags as) a
68+ -> Product tags as
69+ -> (a, Product tags as)
70+runState m = T.runState (coerce m)
ether-suite/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
bench/Bench.hs → ether-suite/bench/Bench.hsrenamed+78−95
@@ -1,14 +1,22 @@
1−{-# OPTIONS -fno-warn-partial-type-signatures #-}
1+{-# LANGUAGE TypeApplications #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE FunctionalDependencies #-}
4+{-# LANGUAGE FlexibleContexts #-}
5+{-# LANGUAGE DataKinds #-}
6+{-# LANGUAGE TypeOperators #-}
27
38module Main (main) where
49
5−import Control.DeepSeq
6−import qualified Control.Lens as L
10+import Criterion.Main
711import qualified Control.Monad.Reader as M
812import qualified Control.Monad.State as M
9−import Criterion.Main
10−import Ether
11−import TupleInstances ()
13+import qualified Control.Monad.Ether.Reader as E
14+import qualified Control.Monad.Ether.State as E
15+import qualified Control.Monad.Ether.Reader.Flatten as E.F
16+import qualified Control.Monad.Ether.State.Flatten as E.F
17+import Control.Ether.Flatten
18+import qualified Control.Lens as L
19+import Control.DeepSeq
1220
1321id' :: a -> a
1422id' = id
@@ -68,124 +76,99 @@ run_stateCombinerMTL_flat_9
6876 M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
6977
7078readerCombinerEther_sep_9
71− :: ( MonadReader 1 Int m
72− , MonadReader 2 Int m
73− , MonadReader 3 Int m
74− , MonadReader 4 Int m
75− , MonadReader 5 Int m
76− , MonadReader 6 Int m
77− , MonadReader 7 Int m
78− , MonadReader 8 Int m
79− , MonadReader 9 Int m )
79+ :: ( E.MonadReader 1 Int m
80+ , E.MonadReader 2 Int m
81+ , E.MonadReader 3 Int m
82+ , E.MonadReader 4 Int m
83+ , E.MonadReader 5 Int m
84+ , E.MonadReader 6 Int m
85+ , E.MonadReader 7 Int m
86+ , E.MonadReader 8 Int m
87+ , E.MonadReader 9 Int m )
8088 => m ()
8189readerCombinerEther_sep_9 = rnf <$> sequenceA
82− [ ask @1
83− , ask @2
84− , ask @3
85− , ask @4
86− , ask @5
87− , ask @6
88− , ask @7
89− , ask @8
90− , ask @9 ]
90+ [ E.ask @1
91+ , E.ask @2
92+ , E.ask @3
93+ , E.ask @4
94+ , E.ask @5
95+ , E.ask @6
96+ , E.ask @7
97+ , E.ask @8
98+ , E.ask @9 ]
9199{-# NOINLINE readerCombinerEther_sep_9 #-}
92100
93101stateCombinerEther_sep_9
94− :: ( MonadState 1 Int m
95− , MonadState 2 Int m
96− , MonadState 3 Int m
97− , MonadState 4 Int m
98− , MonadState 5 Int m
99− , MonadState 6 Int m
100− , MonadState 7 Int m
101− , MonadState 8 Int m
102− , MonadState 9 Int m )
102+ :: ( E.MonadState 1 Int m
103+ , E.MonadState 2 Int m
104+ , E.MonadState 3 Int m
105+ , E.MonadState 4 Int m
106+ , E.MonadState 5 Int m
107+ , E.MonadState 6 Int m
108+ , E.MonadState 7 Int m
109+ , E.MonadState 8 Int m
110+ , E.MonadState 9 Int m )
103111 => m ()
104112stateCombinerEther_sep_9 = do
105− modify @1 id'
106− modify @2 id'
107− modify @3 id'
108− modify @4 id'
109− modify @5 id'
110− modify @6 id'
111− modify @7 id'
112− modify @8 id'
113− modify @9 id'
113+ E.modify @1 id'
114+ E.modify @2 id'
115+ E.modify @3 id'
116+ E.modify @4 id'
117+ E.modify @5 id'
118+ E.modify @6 id'
119+ E.modify @7 id'
120+ E.modify @8 id'
121+ E.modify @9 id'
114122 rnf <$> sequenceA
115− [ get @1
116− , get @2
117− , get @3
118− , get @4
119− , get @5
120− , get @6
121− , get @7
122− , get @8
123− , get @9 ]
124−{-# NOINLINE stateCombinerEther_sep_9 #-}
123+ [ E.get @1
124+ , E.get @2
125+ , E.get @3
126+ , E.get @4
127+ , E.get @5
128+ , E.get @6
129+ , E.get @7
130+ , E.get @8
131+ , E.get @9 ]
125132
126133run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
127134run_readerCombinerEther_nested_9
128135 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
129− = flip (runReader @9) a1
130− . flip (runReaderT @8) a2
131− . flip (runReaderT @7) a3
132− . flip (runReaderT @6) a4
133− . flip (runReaderT @5) a5
134− . flip (runReaderT @4) a6
135− . flip (runReaderT @3) a7
136− . flip (runReaderT @2) a8
137− . flip (runReaderT @1) a9
136+ = flip (E.runReader @9) a1
137+ . flip (E.runReaderT @8) a2
138+ . flip (E.runReaderT @7) a3
139+ . flip (E.runReaderT @6) a4
140+ . flip (E.runReaderT @5) a5
141+ . flip (E.runReaderT @4) a6
142+ . flip (E.runReaderT @3) a7
143+ . flip (E.runReaderT @2) a8
144+ . flip (E.runReaderT @1) a9
138145 $ readerCombinerEther_sep_9
139146
140147run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
141148run_readerCombinerEther_flatten_9
142149 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
143150 =
144− runReaders
151+ E.F.runReader @'[1,2,3,4,5,6,7,8,9]
145152 readerCombinerEther_sep_9
146− ( Tagged @1 a9,
147− Tagged @2 a8,
148− Tagged @3 a7,
149− Tagged @4 a6,
150− Tagged @5 a5,
151− Tagged @6 a4,
152− Tagged @7 a3,
153− Tagged @8 a2,
154− Tagged @9 a1 )
153+ (P9 a9 a8 a7 a6 a5 a4 a3 a2 a1)
154+
155155
156156run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
157157run_readerCombinerEther_flattenhalf_9
158− (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
159− flip runReaders
160− ( Tagged @1 a9,
161− Tagged @2 a8,
162− Tagged @3 a7,
163− Tagged @4 a6 ) .
164− flip runReadersT
165− ( Tagged @5 a5,
166− Tagged @6 a4,
167− Tagged @7 a3,
168− Tagged @8 a2,
169− Tagged @9 a1 ) $
170− readerCombinerEther_sep_9
158+ (a1, a2, a3, a4, a5, a6, a7, a8, a9)
159+ = flip (E.F.runReader @'[1,2,3,4]) (P4 a9 a8 a7 a6)
160+ . flip (E.F.runReaderT @'[5,6,7,8,9]) (P5 a5 a4 a3 a2 a1)
161+ $ readerCombinerEther_sep_9
171162
172163run_stateCombinerEther_flatten_9 ::
173164 (Int, Int, Int, Int, Int, Int, Int, Int, Int) ->
174− ((), _)
165+ ((), Product '[1,2,3,4,5,6,7,8,9] '[Int,Int,Int,Int,Int,Int,Int,Int,Int])
175166run_stateCombinerEther_flatten_9
176167 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
177168 =
178− runStates
169+ E.F.runState
179170 stateCombinerEther_sep_9
180− ( Tagged @1 a9,
181− Tagged @2 a8,
182− Tagged @3 a7,
183− Tagged @4 a6,
184− Tagged @5 a5,
185− Tagged @6 a4,
186− Tagged @7 a3,
187− Tagged @8 a2,
188− Tagged @9 a1 )
171+ (P9 a9 a8 a7 a6 a5 a4 a3 a2 a1)
189172
190173tuple_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int)
191174tuple_9 = (1, -2, 3, -4, 5, -6, 7, -8, 9)
ether-suite/ether-suite.cabalnew file+71
@@ -0,0 +1,71 @@
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: base >=4.9 && <4.10
13+ , transformers >=0.4.2
14+ , mtl >=2.2.1
15+ , tasty >=0.10
16+ , tasty-quickcheck >=0.8
17+ , QuickCheck >=2.8
18+ , ghc-prim >=0.3
19+ , lens >=4.14
20+ , ether
21+ , ether-zoom
22+
23+ main-is: Regression.hs
24+ other-modules: Regression.T1
25+ Regression.T2
26+ Regression.T3
27+ Regression.T4
28+ Regression.T5
29+ Regression.T6
30+ Regression.T7
31+ Regression.T8
32+ Regression.T9
33+ Regression.T10
34+ Regression.T11
35+ Regression.T12
36+
37+ type: exitcode-stdio-1.0
38+ hs-source-dirs: test
39+ default-language: Haskell2010
40+ default-extensions: ConstraintKinds
41+ DataKinds
42+ EmptyDataDecls
43+ FlexibleContexts
44+ GeneralizedNewtypeDeriving
45+ LambdaCase
46+ PolyKinds
47+ ScopedTypeVariables
48+ TypeApplications
49+ TypeFamilies
50+ TypeOperators
51+ ghc-options: -Wall -fno-warn-missing-signatures
52+
53+
54+benchmark bench
55+
56+ build-depends: base >=4.9 && <4.10
57+ , mtl >=2.2.1
58+ , transformers >=0.4.2
59+ , criterion >=1.1
60+ , deepseq >=1.4
61+ , lens >=4.14
62+ , ether
63+ , ether-flatten
64+
65+ main-is: Bench.hs
66+
67+ type: exitcode-stdio-1.0
68+ hs-source-dirs: bench
69+ default-language: Haskell2010
70+ ghc-options: -Wall -O2
71+ ghc-prof-options: -fprof-auto
test/Regression.hs → ether-suite/test/Regression.hsrenamed

The content is the same.

test/Regression/T1.hs → ether-suite/test/Regression/T1.hsrenamed+5−16
@@ -1,8 +1,7 @@
11module Regression.T1 (test1) where
22
3−import Ether
4−import TupleInstances ()
5−import Data.List (group)
3+import Control.Monad.Ether
4+import Control.Ether.Abbr
65
76import Test.Tasty
87import Test.Tasty.QuickCheck
@@ -11,7 +10,7 @@ data Tag1
1110data Tag2
1211
1312testEther
14− :: (MonadReader Tag1 String m, MonadReader Tag2 String m)
13+ :: Ether '[Tag1 --> String, Tag2 --> String] m
1514 => m ((String, String), (String, String))
1615testEther = do
1716 s1 <- ask @Tag1
@@ -25,10 +24,6 @@ testEther = do
2524
2625runner1 s1 s2 = flip (runReader @Tag1) s1 . flip (runReaderT @Tag2) s2
2726runner2 s1 s2 = flip (runReader @Tag2) s2 . flip (runReaderT @Tag1) s1
28−runner3 s1 s2 = flip runReaders (Tagged @Tag1 s1, Tagged @Tag2 s2)
29−
30−same :: Eq a => [a] -> Bool
31−same = (<=1) . length . group
3227
3328test1 :: TestTree
3429test1 = testGroup "T1: Reader local environment"
@@ -38,13 +33,7 @@ test1 = testGroup "T1: Reader local environment"
3833 , testProperty "runner₂ works"
3934 $ \s1 s2 -> property
4035 $ runner2 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
41− , testProperty "runner₃ works"
42− $ \s1 s2 -> property
43− $ runner3 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
44− , testProperty "runner₁ == runner₂ == runner₃"
36+ , testProperty "runner₁ == runner₂"
4537 $ \s1 s2 -> property
46− $ same
47− [ runner1 s1 s2 testEther
48− , runner2 s1 s2 testEther
49− , runner3 s1 s2 testEther ]
38+ $ runner1 s1 s2 testEther == runner2 s1 s2 testEther
5039 ]
test/Regression/T10.hs → ether-suite/test/Regression/T10.hsrenamed+10−11
@@ -2,23 +2,22 @@ module Regression.T10 (test10) where
22
33import Control.Applicative
44import Data.Functor.Identity
5−
6−import Ether
5+import qualified Control.Monad.Ether.Implicit as I
76
87import Test.Tasty
98import Test.Tasty.QuickCheck
109
11−testEther :: Integer -> StateT' Integer Maybe [Integer]
10+testEther :: Integer -> I.StateT Integer Maybe [Integer]
1211testEther m = range
1312 where
1413 range = liftA2 (:) yield (range <|> pure [])
15− yield = stateT' $ \n -> do
16− guard (n <= m)
14+ yield = I.stateT $ \n -> do
15+ I.guard (n <= m)
1716 Just (n, n + 1)
1817
19−testEther' :: Integer -> State' Integer [Integer]
18+testEther' :: Integer -> I.State Integer [Integer]
2019testEther' m =
21− stateT' $ Identity . maybe ([], m + 1) id . runStateT' (testEther m)
20+ I.stateT $ Identity . maybe ([], m + 1) id . I.runStateT (testEther m)
2221
2322next1 :: Integer -> Integer -> Maybe Integer
2423next1 m n
@@ -33,11 +32,11 @@ range1 m n
3332test10 :: TestTree
3433test10 = testGroup "T10: Alternative instance"
3534 [ testProperty "execStateT works"
36− $ \m n -> execStateT' (testEther m) n == next1 m n
35+ $ \m n -> I.execStateT (testEther m) n == next1 m n
3736 , testProperty "evalStateT works"
38− $ \m n -> evalStateT' (testEther m) n == range1 m n
37+ $ \m n -> I.evalStateT (testEther m) n == range1 m n
3938 , testProperty "execState works"
40− $ \m n -> execState' (testEther' m) n == m + 1
39+ $ \m n -> I.execState (testEther' m) n == m + 1
4140 , testProperty "evalState works"
42− $ \m n -> evalState' (testEther' m) n == [n..m]
41+ $ \m n -> I.evalState (testEther' m) n == [n..m]
4342 ]
test/Regression/T11.hs → ether-suite/test/Regression/T11.hsrenamed+4−4
@@ -1,8 +1,8 @@
11module Regression.T11 (test11) where
22
3−import Ether
4−
53import Data.Bool
4+import Control.Monad.Ether
5+
66import qualified Control.Monad.State as T
77import qualified Control.Monad.Reader as T
88
@@ -28,12 +28,12 @@ model n = zipWith ($) (cycle [id, negate]) [n..]
2828
2929runner1 n
3030 = flip (T.runReader) n
31− . flip (execLazyStateT @STag) []
31+ . flip (execStateT @STag) []
3232 . flip T.evalStateT False
3333
3434runner2 n
3535 = flip T.evalState False
36− . flip (execLazyStateT @STag) []
36+ . flip (execStateT @STag) []
3737 . flip T.runReaderT n
3838
3939test11 :: TestTree
test/Regression/T12.hs → ether-suite/test/Regression/T12.hsrenamed+4−3
@@ -1,6 +1,7 @@
11module Regression.T12 (test12) where
22
3−import Ether
3+import Control.Monad.Ether.State
4+import Control.Monad.Ether.State.Zoom
45import Control.Lens
56
67import Test.Tasty
@@ -13,8 +14,8 @@ succState = modify @Foo succ
1314
1415testEther :: (Enum a, MonadState Foo (a, a) m) => m (a, a)
1516testEther = do
16− Ether.zoom @Foo _1 succState
17− Ether.zoom @Foo _2 $ modify @Foo pred
17+ tagZoom @Foo _1 succState
18+ tagZoom @Foo _2 $ modify @Foo pred
1819 get @Foo
1920
2021model :: Enum a => (a, a) -> (a, a)
test/Regression/T2.hs → ether-suite/test/Regression/T2.hsrenamed+9−7
@@ -1,18 +1,20 @@
11module Regression.T2 (test2) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import qualified Control.Monad.Ether.Implicit as I
5+import qualified Control.Ether.Implicit.Abbr as I
46
57import Test.Tasty
68import Test.Tasty.QuickCheck
79
8−testEther :: (MonadReader' Integer m, MonadReader' Bool m) => m String
9−testEther = local' (succ :: Integer -> Integer) $ do
10− n :: Integer <- asks' (*2)
11− b <- local' not ask'
10+testEther :: Ether '[I.R Integer, I.R Bool] m => m String
11+testEther = I.local (succ :: Integer -> Integer) $ do
12+ n :: Integer <- I.asks (*2)
13+ b <- I.local not I.ask
1214 return (if b then "" else show n)
1315
14−runner1 (n :: Integer) = flip runReader' n . flip runReaderT' True
15−runner2 (n :: Integer) = flip runReader' True . flip runReaderT' n
16+runner1 (n :: Integer) = flip I.runReader n . flip I.runReaderT True
17+runner2 (n :: Integer) = flip I.runReader True . flip I.runReaderT n
1618
1719test2 :: TestTree
1820test2 = testGroup "T2: Implicit tags"
test/Regression/T3.hs → ether-suite/test/Regression/T3.hsrenamed+3−2
@@ -1,6 +1,7 @@
11module Regression.T3 (test3) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import qualified Control.Monad.Reader as T
67import qualified Control.Monad.State as T
@@ -19,7 +20,7 @@ testMTL = do
1920 return (a * b)
2021
2122testEther
22− :: (MonadReader STag Int m, MonadState STag Int m, MonadReader RTag Int m)
23+ :: Ether '[STag --> Int, STag <-> Int, RTag --> Int] m
2324 => m (Int, Int, Int)
2425testEther = local @RTag (*2) $ do
2526 a_mul_b <- tagAttach @STag testMTL
test/Regression/T4.hs → ether-suite/test/Regression/T4.hsrenamed+3−2
@@ -1,13 +1,14 @@
11module Regression.T4 (test4) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import Test.Tasty
67import Test.Tasty.QuickCheck
78
89data RTag
910
10−testEther :: MonadReader RTag Int m => m Int
11+testEther :: Ether '[RTag --> Int] m => m Int
1112testEther = ask @RTag
1213
1314runner r
test/Regression/T5.hs → ether-suite/test/Regression/T5.hsrenamed+11−8
@@ -1,6 +1,9 @@
11module Regression.T5 (test5) where
22
3−import Ether
3+import Control.Ether.Abbr
4+
5+import qualified Control.Monad.Ether.Implicit as I
6+import qualified Control.Ether.Implicit.Abbr as I
47
58import Test.Tasty
69import Test.Tasty.QuickCheck
@@ -13,22 +16,22 @@ incCounter = succ
1316
1417testEther
1518 :: (Num a, Ord a)
16− => (MonadReader' a m, MonadState' Counter m)
19+ => Ether '[I.R a, I.S Counter] m
1720 => m a
1821testEther = do
19− a <- ask'
22+ a <- I.ask
2023 if a <= 0
2124 then do
22− put' (0 :: Counter)
25+ I.put (0 :: Counter)
2326 return 1
2427 else do
25− modify' incCounter -- overriden in the base case
26− b <- runReaderT' testEther (a - 1)
27− modify' incCounter
28+ I.modify incCounter -- overriden in the base case
29+ b <- I.runReaderT testEther (a - 1)
30+ I.modify incCounter
2831 return (a * b)
2932
3033runner :: (Num a, Ord a) => a -> (a, Counter)
31−runner a = runState' (runReaderT' testEther a) (0 :: Counter)
34+runner a = I.runState (I.runReaderT testEther a) (0 :: Counter)
3235
3336factorial :: (Num a, Enum a) => a -> a
3437factorial a = product [1..a]
test/Regression/T6.hs → ether-suite/test/Regression/T6.hsrenamed+16−14
@@ -1,7 +1,10 @@
11module Regression.T6 (test6) where
22
3−import Data.Function
4−import Ether
3+import Control.Monad
4+import Control.Ether.Abbr
5+
6+import qualified Control.Monad.Ether.Implicit as I
7+import qualified Control.Ether.Implicit.Abbr as I
58
69import Test.Tasty
710import Test.Tasty.QuickCheck
@@ -14,33 +17,32 @@ data NegativeLog a = NegativeLog a
1417
1518testEther
1619 :: (Floating a, Ord a)
17− => (MonadExcept' DivideByZero m, MonadExcept' (NegativeLog a) m)
20+ => Ether '[I.E DivideByZero, I.E (NegativeLog a)] m
1821 => a -> a -> m a
1922testEther a b = do
20− when (b == 0) (throw' DivideByZero)
23+ when (b == 0) (I.throw DivideByZero)
2124 let d = a / b
22− when (d < 0) (throw' (NegativeLog d))
25+ when (d < 0) (I.throw (NegativeLog d))
2326 return (log d)
2427
28+-- Copied verbatim from "Data.Function" to support @base < 4.8@.
29+(&) :: a -> (a -> b) -> b
30+x & f = f x
31+
2532handleNegativeLog (NegativeLog (x :: Double)) = "nl: " ++ show x
2633handleDivideByZero DivideByZero = "dz"
2734
28−handleT' :: Functor m => (e -> a) -> ExceptT' e m a -> m a
29−handleT' h m = fmap (either h id) (runExceptT' m)
30−
3135runner1 :: Double -> Double -> String
3236runner1 a b = do
3337 (show `fmap` testEther a b)
34− & handleT' handleNegativeLog
35− & handleT' handleDivideByZero
36− & runIdentity
38+ & I.handleT handleNegativeLog
39+ & I.handle handleDivideByZero
3740
3841runner2 :: Double -> Double -> String
3942runner2 a b = do
4043 (show `fmap` testEther a b)
41− & handleT' handleDivideByZero
42− & handleT' handleNegativeLog
43− & runIdentity
44+ & I.handleT handleDivideByZero
45+ & I.handle handleNegativeLog
4446
4547logDiv :: Double -> Double -> String
4648logDiv a b
test/Regression/T7.hs → ether-suite/test/Regression/T7.hsrenamed+1−1
@@ -3,7 +3,7 @@ module Regression.T7 (test7) where
33import Data.Monoid
44import Control.Monad
55
6−import Ether
6+import Control.Monad.Ether
77import qualified Control.Monad.Writer as T
88
99import Test.Tasty
test/Regression/T8.hs → ether-suite/test/Regression/T8.hsrenamed+3−2
@@ -1,6 +1,7 @@
11module Regression.T8 (test8) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import qualified Control.Monad.State as T
67
@@ -17,7 +18,7 @@ testMTL2 :: T.MonadState Bool m => m ()
1718testMTL2 = T.modify not
1819
1920testEther
20− :: (MonadState Foo Int m, MonadState Bar Bool m)
21+ :: Ether '[Foo <-> Int, Bar <-> Bool] m
2122 => m String
2223testEther = do
2324 tagAttach @Foo testMTL1
test/Regression/T9.hs → ether-suite/test/Regression/T9.hsrenamed+5−4
@@ -1,6 +1,7 @@
11module Regression.T9 (test9) where
22
3−import Ether
3+import Control.Ether.Abbr
4+import Control.Monad.Ether
45
56import Test.Tasty
67import Test.Tasty.QuickCheck
@@ -8,16 +9,16 @@ import Test.Tasty.QuickCheck
89data Foo
910data Bar
1011
11−testEther1 :: MonadState Foo Int m => m String
12+testEther1 :: Ether '[Foo <-> Int] m => m String
1213testEther1 = do
1314 modify @Foo negate
1415 gets @Foo show
1516
16−testEther2 :: MonadState Bar Int m => m String
17+testEther2 :: Ether '[Bar <-> Int] m => m String
1718testEther2 = tagReplace @Foo @Bar testEther1
1819
1920testEther
20− :: (MonadState Foo Int m, MonadState Bar Int m)
21+ :: Ether '[Foo <-> Int, Bar <-> Int] m
2122 => m String
2223testEther = do
2324 a <- testEther1
ether-zoom/CHANGELOG.mdnew file

No changes to the content.

ether-zoom/LICENSEnew file+30
@@ -0,0 +1,30 @@
1+Copyright (c) 2017, Vladislav Zavialov
2+
3+All rights reserved.
4+
5+Redistribution and use in source and binary forms, with or without
6+modification, are permitted provided that the following conditions are met:
7+
8+ * Redistributions of source code must retain the above copyright
9+ notice, this list of conditions and the following disclaimer.
10+
11+ * Redistributions in binary form must reproduce the above
12+ copyright notice, this list of conditions and the following
13+ disclaimer in the documentation and/or other materials provided
14+ with the distribution.
15+
16+ * Neither the name of Vladislav Zavialov nor the names of other
17+ contributors may be used to endorse or promote products derived
18+ from this software without specific prior written permission.
19+
20+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ether-zoom/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
ether-zoom/ether-zoom.cabalnew file+40
@@ -0,0 +1,40 @@
1+name: ether-zoom
2+version: 0.1.0.0
3+synopsis: Zoom for the state monad
4+description:
5+ Zoom into parts of a state using a lens.
6+
7+category: Control
8+license: BSD3
9+license-file: LICENSE
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+cabal-version: >=1.18
16+extra-source-files: CHANGELOG.md
17+
18+source-repository head
19+
20+ type: git
21+ location: git@github.com:int-index/ether.git
22+
23+
24+library
25+
26+ exposed-modules: Control.Monad.Ether.State.Zoom
27+ build-depends: base >=4.9 && <4.10
28+ , ether >=0.5 && <0.6
29+ , transformers >=0.5
30+ , lens >=4.14
31+ , reflection >=2.1
32+
33+ default-language: Haskell2010
34+ default-extensions: PolyKinds
35+ ScopedTypeVariables
36+ FunctionalDependencies
37+ TypeApplications
38+
39+ hs-source-dirs: src
40+ ghc-options: -Wall -O2
ether-zoom/src/Control/Monad/Ether/State/Zoom.hsnew file+50
@@ -0,0 +1,50 @@
1+{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
2+
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE RankNTypes #-}
5+{-# LANGUAGE TypeSynonymInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE FlexibleContexts #-}
8+{-# LANGUAGE UndecidableInstances #-}
9+{-# LANGUAGE TypeFamilies #-}
10+
11+module Control.Monad.Ether.State.Zoom
12+ ( TAG_ZOOM
13+ , TagZoomT
14+ , tagZoom
15+ ) where
16+
17+import Control.Lens
18+import Data.Reflection
19+import Control.Monad.Trans.Ether.Handler
20+import Control.Monad.Trans.Identity
21+import Control.Monad.Ether.State.Class
22+import Data.Proxy
23+import Data.Coerce
24+
25+-- | Encode type-level information for 'tagZoom'.
26+data TAG_ZOOM t z
27+
28+type TagZoomT t (z :: *) = Handler (TAG_ZOOM t z) IdentityT
29+
30+-- | Zoom into a part of a state using a lens.
31+tagZoom
32+ :: forall tag sOuter sInner m a
33+ . Lens' sOuter sInner
34+ -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => TagZoomT tag z m a)
35+ -> m a
36+tagZoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
37+
38+instance
39+ ( MonadState tag sOuter m
40+ , Reifies z (ReifiedLens' sOuter sInner)
41+ , trans ~ IdentityT
42+ ) => MonadState tag sInner (Handler (TAG_ZOOM tag z) trans m)
43+ where
44+ state =
45+ (coerce :: forall dp r a .
46+ (r -> m a) ->
47+ (r -> Handler dp trans m a))
48+ (state @tag . l)
49+ where
50+ Lens l = reflect (Proxy :: Proxy z)
ether.cabaldeleted−237
@@ -1,237 +0,0 @@
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
CHANGELOG.md → ether/CHANGELOG.mdrenamed+3−17
@@ -1,25 +1,11 @@
1−0.5.1.0
2−-------
3−
4−* Disable `HasLens` for tuples via cabal flag.
5−
610.5.0.0
72-------
83
9−* Support only GHC 8.0 and higher.
10−* Use the `TypeApplications` extension to get rid of `Proxy`.
4+* Support GHC 8.0 only.
5+* Utilize the `TypeApplications` extension.
116* Remove `Control.Ether.TH`.
12−* Remove `Control.Ether.Abbr`.
13−* Unify `Dispatch` and `TaggedTrans`.
14−* Better `MonadBase` and `MonadBaseControl` instances.
15−* Add flattening for `ReaderT` and `StateT`.
16−* Add zooming for `MonadState`.
17−* Simpler module structure.
18−
19−0.4.1.0
20−-------
7+* Use `Proxy#` in class methods.
218
22−* Export DispatchT newtype constructor.
239
24100.4.0.0
2511-------
ether/LICENSEnew file+30
@@ -0,0 +1,30 @@
1+Copyright (c) 2017, Vladislav Zavialov
2+
3+All rights reserved.
4+
5+Redistribution and use in source and binary forms, with or without
6+modification, are permitted provided that the following conditions are met:
7+
8+ * Redistributions of source code must retain the above copyright
9+ notice, this list of conditions and the following disclaimer.
10+
11+ * Redistributions in binary form must reproduce the above
12+ copyright notice, this list of conditions and the following
13+ disclaimer in the documentation and/or other materials provided
14+ with the distribution.
15+
16+ * Neither the name of Vladislav Zavialov nor the names of other
17+ contributors may be used to endorse or promote products derived
18+ from this software without specific prior written permission.
19+
20+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ether/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
ether/ether.cabalnew file+81
@@ -0,0 +1,81 @@
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: Control.Ether.Abbr
30+ Control.Ether.Implicit.Abbr
31+ Control.Monad.Trans.Ether.Handler
32+ Control.Monad.Ether
33+ Control.Monad.Ether.TagAttach
34+ Control.Monad.Ether.TagReplace
35+ Control.Monad.Ether.Reader
36+ Control.Monad.Ether.Reader.Class
37+ Control.Monad.Ether.Writer
38+ Control.Monad.Ether.Writer.Class
39+ Control.Monad.Ether.State
40+ Control.Monad.Ether.State.Class
41+ Control.Monad.Ether.State.Lazy
42+ Control.Monad.Ether.State.Strict
43+ Control.Monad.Ether.Except
44+ Control.Monad.Ether.Except.Class
45+ Control.Monad.Ether.Implicit
46+ Control.Monad.Ether.Implicit.Reader
47+ Control.Monad.Ether.Implicit.Writer
48+ Control.Monad.Ether.Implicit.State
49+ Control.Monad.Ether.Implicit.State.Lazy
50+ Control.Monad.Ether.Implicit.State.Strict
51+ Control.Monad.Ether.Implicit.Except
52+
53+ other-modules: Control.Monad.Ether.State.Common
54+
55+ build-depends: base >=4.9 && <4.10
56+ , transformers >=0.4.2
57+ , transformers-lift >=0.1.0.1
58+ , mtl >=2.2.1
59+ , mmorph >=1.0.4
60+ , monad-control >=1.0.0.4
61+ , transformers-base >=0.4.4
62+ , exceptions >=0.8
63+ , ghc-prim >=0.3
64+
65+ default-language: Haskell2010
66+ default-extensions: PolyKinds
67+ ScopedTypeVariables
68+ FunctionalDependencies
69+ TypeApplications
70+ other-extensions: ConstraintKinds
71+ DataKinds
72+ DefaultSignatures
73+ DeriveGeneric
74+ FlexibleInstances
75+ GeneralizedNewtypeDeriving
76+ TypeFamilies
77+ TypeOperators
78+ UndecidableInstances
79+
80+ hs-source-dirs: src
81+ ghc-options: -Wall -O2
ether/src/Control/Ether/Abbr.hsnew file+60
@@ -0,0 +1,60 @@
1+{-# LANGUAGE EmptyDataDecls #-}
2+{-# LANGUAGE TypeOperators #-}
3+{-# LANGUAGE ConstraintKinds #-}
4+{-# LANGUAGE DataKinds #-}
5+{-# LANGUAGE TypeFamilies #-}
6+
7+-- | Abbreviations for constraints.
8+
9+module Control.Ether.Abbr
10+ ( type (-->)
11+ , type (<--)
12+ , type (<->)
13+ , type (-!-)
14+ , Ether
15+ , ReifyAbbr
16+ ) where
17+
18+import GHC.Exts (Constraint)
19+
20+import Control.Monad.Ether
21+
22+-- | Turns an abbreviation into an actual constraint.
23+type family ReifyAbbr (abbr :: *) (m :: * -> *) :: Constraint
24+
25+-- | Denotes 'MonadReader'. The mnemonic is that you read values of type @r@
26+-- from the reader environment tagged by @tag@, thus the arrows points
27+-- from @tag@ to @r@.
28+data tag --> r
29+type instance ReifyAbbr (tag --> r) m = MonadReader tag r m
30+
31+-- | Denotes 'MonadWriter'. The mnemonic is that you write values of type @w@
32+-- to the writer accumulator tagged by @tag@, thus the arrows points
33+-- from @w@ to @tag@.
34+data tag <-- w
35+type instance ReifyAbbr (tag <-- w) m = MonadWriter tag w m
36+
37+-- | Denotes 'MonadState'. The mnemonic is that you can both read from and
38+-- write into the state, thus the arrow points in both directions.
39+data tag <-> s
40+type instance ReifyAbbr (tag <-> s) m = MonadState tag s m
41+
42+-- | Denotes 'MonadExcept'.
43+data tag -!- e
44+type instance ReifyAbbr (tag -!- e) m = MonadExcept tag e m
45+
46+-- | Reify a list of constraint abbreviations.
47+--
48+-- > f :: Ether '[Foo --> r, Bar <-- w, Baz <-> s, Quux -!- e] m => m a
49+--
50+-- expands into
51+--
52+-- > f :: ( MonadReader Foo r m
53+-- > , MonadWriter Bar w m
54+-- > , MonadState Baz s m
55+-- > , MonadExcept Quux e m
56+-- > ) => m a
57+
58+type family Ether (abbrs :: [*]) m :: Constraint where
59+ Ether '[] m = ()
60+ Ether (abbr ': abbrs) m = (ReifyAbbr abbr m, Ether abbrs m)
ether/src/Control/Ether/Implicit/Abbr.hsnew file+25
@@ -0,0 +1,25 @@
1+{-# LANGUAGE TypeFamilies #-}
2+
3+-- | See "Control.Ether.Abbr".
4+
5+module Control.Ether.Implicit.Abbr (R, W, S, E) where
6+
7+import Control.Ether.Abbr (ReifyAbbr)
8+import Control.Monad.Ether.Implicit
9+
10+-- | Denotes 'MonadReader'.
11+data R r
12+type instance ReifyAbbr (R r) m = MonadReader r m
13+
14+-- | Denotes 'MonadWriter'.
15+data W w
16+type instance ReifyAbbr (W w) m = MonadWriter w m
17+
18+-- | Denotes 'MonadState'.
19+data S s
20+type instance ReifyAbbr (S s) m = MonadState s m
21+
22+-- | Denotes 'MonadExcept'.
23+data E e
24+type instance ReifyAbbr (E e) m = MonadExcept e m
25+
ether/src/Control/Monad/Ether.hsnew file+13
@@ -0,0 +1,13 @@
1+-- | This module provides convenience exports of all
2+-- tagged monad classes from Ether.
3+
4+module Control.Monad.Ether (module X) where
5+
6+import Control.Monad as X
7+import Control.Monad.Fix as X
8+import Control.Monad.Ether.Reader as X
9+import Control.Monad.Ether.Writer as X
10+import Control.Monad.Ether.State as X
11+import Control.Monad.Ether.Except as X
12+import Control.Monad.Ether.TagAttach as X
13+import Control.Monad.Ether.TagReplace as X
ether/src/Control/Monad/Ether/Except.hsnew file+83
@@ -0,0 +1,83 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE UndecidableInstances #-}
4+{-# LANGUAGE TypeFamilies #-}
5+{-# LANGUAGE AllowAmbiguousTypes #-}
6+
7+-- | See "Control.Monad.Except".
8+
9+module Control.Monad.Ether.Except
10+ (
11+ -- * MonadExcept class
12+ MonadExcept
13+ , throw
14+ , catch
15+ -- * The Except monad
16+ , Except
17+ , runExcept
18+ -- * The ExceptT monad transformer
19+ , ExceptT
20+ , exceptT
21+ , runExceptT
22+ -- * Handle functions
23+ , handleT
24+ , handle
25+ ) where
26+
27+import Control.Monad.Ether.Except.Class
28+import qualified Control.Monad.Trans.Ether.Handler as D
29+import qualified Control.Monad.Except as T
30+import Control.Monad.Signatures (Catch)
31+import Data.Functor.Identity
32+import Data.Coerce
33+
34+-- | Runs an 'Except' and handles the exception with the given function.
35+handle :: forall tag e a . (e -> a) -> Except tag e a -> a
36+handle h m = runIdentity (handleT @tag h m)
37+
38+-- | Runs an 'ExceptT' and handles the exception with the given function.
39+handleT :: forall tag e m a . Functor m => (e -> a) -> ExceptT tag e m a -> m a
40+handleT h m = fmap (either h id) (runExceptT @tag m)
41+
42+-- | Encode type-level information for 'ExceptT'.
43+data EXCEPT
44+
45+-- | The parameterizable exception monad.
46+--
47+-- Computations are either exceptions or normal values.
48+--
49+-- The 'return' function returns a normal value, while '>>=' exits on
50+-- the first exception.
51+type Except tag e = ExceptT tag e Identity
52+
53+-- | The exception monad transformer.
54+--
55+-- The 'return' function returns a normal value, while '>>=' exits on
56+-- the first exception.
57+type ExceptT tag e = D.Handler '(EXCEPT, tag) (T.ExceptT e)
58+
59+-- | Runs an 'Except' and returns either an exception or a normal value.
60+runExcept :: forall tag e a . Except tag e a -> Either e a
61+runExcept = coerce (T.runExcept @e @a)
62+
63+-- | Runs an 'ExceptT' and returns either an exception or a normal value.
64+runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
65+runExceptT = coerce (T.runExceptT @e @m @a)
66+
67+-- | Constructor for computations in the exception monad transformer.
68+exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
69+exceptT = coerce (T.ExceptT @e @m @a)
70+
71+instance
72+ ( T.MonadError e (trans m) -- FIXME: (forall m . T.MonadError e (trans m))
73+ ) => MonadExcept tag e (D.Handler '(EXCEPT, tag) trans (m :: * -> *))
74+ where
75+ throw =
76+ coerce (T.throwError @e @(trans m) @a) ::
77+ forall dp a . e -> D.Handler dp trans m a
78+ {-# INLINE throw #-}
79+
80+ catch =
81+ coerce (T.catchError @e @(trans m) @a) ::
82+ forall dp a . Catch e (D.Handler dp trans m) a
83+ {-# INLINE catch #-}
ether/src/Control/Monad/Ether/Except/Class.hsnew file+30
@@ -0,0 +1,30 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE UndecidableInstances #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE AllowAmbiguousTypes #-}
5+
6+-- | See "Control.Monad.Except".
7+
8+module Control.Monad.Ether.Except.Class
9+ ( MonadExcept(..)
10+ ) where
11+
12+import qualified Control.Monad.Trans.Lift.Catch as Lift
13+
14+-- | See 'Control.Monad.Except.MonadError'.
15+class Monad m => MonadExcept tag e m | m tag -> e where
16+
17+ -- | Is used within a monadic computation to begin exception processing.
18+ throw :: e -> m a
19+
20+ -- | A handler function to handle previous exceptions and return to
21+ -- normal execution.
22+ catch :: m a -> (e -> m a) -> m a
23+
24+instance {-# OVERLAPPABLE #-}
25+ ( Lift.LiftCatch t
26+ , Monad (t m)
27+ , MonadExcept tag e m
28+ ) => MonadExcept tag e (t m) where
29+ throw = Lift.lift . throw @tag
30+ catch = Lift.liftCatch (catch @tag)
ether/src/Control/Monad/Ether/Implicit.hsnew file+13
@@ -0,0 +1,13 @@
1+-- | This module provides convenience exports of all
2+-- implicitly tagged monad classes from Ether.
3+
4+module Control.Monad.Ether.Implicit (module X) where
5+
6+import Control.Monad as X
7+import Control.Monad.Fix as X
8+import Control.Monad.Ether.Implicit.Reader as X
9+import Control.Monad.Ether.Implicit.Writer as X
10+import Control.Monad.Ether.Implicit.State as X
11+import Control.Monad.Ether.Implicit.Except as X
12+import Control.Monad.Ether.TagAttach as X
13+import Control.Monad.Ether.TagReplace as X
ether/src/Control/Monad/Ether/Implicit/Except.hsnew file+60
@@ -0,0 +1,60 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+
3+-- | See "Control.Monad.Ether.Except".
4+
5+module Control.Monad.Ether.Implicit.Except
6+ (
7+ -- * MonadExcept class
8+ MonadExcept
9+ , throw
10+ , catch
11+ -- * The Except monad
12+ , Except
13+ , runExcept
14+ -- * The ExceptT monad transformer
15+ , ExceptT
16+ , exceptT
17+ , runExceptT
18+ -- * Handle functions
19+ , handle
20+ , handleT
21+ ) where
22+
23+import qualified Control.Monad.Ether.Except as A
24+
25+-- | See 'Control.Monad.Ether.Except.MonadExcept'.
26+type MonadExcept e = A.MonadExcept e e
27+
28+-- | See 'Control.Monad.Ether.Except.throw'.
29+throw :: forall e m a . MonadExcept e m => e -> m a
30+throw = A.throw @e
31+
32+-- | See 'Control.Monad.Ether.Except.catch'.
33+catch :: forall e m a . MonadExcept e m => m a -> (e -> m a) -> m a
34+catch = A.catch @e
35+
36+-- | See 'Control.Monad.Ether.Except.Except'.
37+type Except e = A.Except e e
38+
39+-- | See 'Control.Monad.Ether.Except.runExcept'.
40+runExcept :: Except e a -> Either e a
41+runExcept = A.runExcept
42+
43+-- | See 'Control.Monad.Ether.Except.ExceptT'.
44+type ExceptT e = A.ExceptT e e
45+
46+-- | See 'Control.Monad.Ether.Except.exceptT'.
47+exceptT :: m (Either e a) -> ExceptT e m a
48+exceptT = A.exceptT
49+
50+-- | See 'Control.Monad.Ether.Except.runExceptT'.
51+runExceptT :: ExceptT e m a -> m (Either e a)
52+runExceptT = A.runExceptT
53+
54+-- | See 'Control.Monad.Ether.Except.handle'.
55+handle :: (e -> a) -> Except e a -> a
56+handle = A.handle
57+
58+-- | See 'Control.Monad.Ether.Except.handleT'.
59+handleT :: Functor m => (e -> a) -> ExceptT e m a -> m a
60+handleT = A.handleT
ether/src/Control/Monad/Ether/Implicit/Reader.hsnew file+59
@@ -0,0 +1,59 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+
3+-- | See "Control.Monad.Ether.Reader".
4+
5+module Control.Monad.Ether.Implicit.Reader
6+ (
7+ -- * MonadReader class
8+ MonadReader
9+ , local
10+ , ask
11+ , reader
12+ , asks
13+ -- * The Reader monad
14+ , Reader
15+ , runReader
16+ -- * The ReaderT monad transformer
17+ , ReaderT
18+ , readerT
19+ , runReaderT
20+ ) where
21+
22+import qualified Control.Monad.Ether.Reader as A
23+
24+-- | See 'Control.Monad.Ether.Reader.ReaderT'.
25+type ReaderT r = A.ReaderT r r
26+
27+-- | See 'Control.Monad.Ether.Reader.readerT'.
28+readerT :: (r -> m a) -> ReaderT r m a
29+readerT = A.readerT
30+
31+-- | See 'Control.Monad.Ether.Reader.runReaderT'.
32+runReaderT :: ReaderT r m a -> r -> m a
33+runReaderT = A.runReaderT
34+
35+-- | See 'Control.Monad.Ether.Reader.Reader'.
36+type Reader r = A.Reader r r
37+
38+-- | See 'Control.Monad.Ether.Reader.runReader'.
39+runReader :: Reader r a -> r -> a
40+runReader = A.runReader
41+
42+-- | See 'Control.Monad.Ether.Reader.MonadReader'.
43+type MonadReader r = A.MonadReader r r
44+
45+-- | See 'Control.Monad.Ether.Reader.local'.
46+local :: forall r m a . MonadReader r m => (r -> r) -> m a -> m a
47+local = A.local @r
48+
49+-- | See 'Control.Monad.Ether.Reader.ask'.
50+ask :: forall r m . MonadReader r m => m r
51+ask = A.ask @r
52+
53+-- | See 'Control.Monad.Ether.Reader.reader'.
54+reader :: forall r m a . MonadReader r m => (r -> a) -> m a
55+reader = A.reader @r
56+
57+-- | See 'Control.Monad.Ether.Reader.asks'.
58+asks :: forall r m a . MonadReader r m => (r -> a) -> m a
59+asks = A.asks @r
ether/src/Control/Monad/Ether/Implicit/State.hsnew file+7
@@ -0,0 +1,7 @@
1+-- | See "Control.Monad.Ether.State".
2+
3+module Control.Monad.Ether.Implicit.State
4+ ( module Control.Monad.Ether.Implicit.State.Lazy
5+ ) where
6+
7+import Control.Monad.Ether.Implicit.State.Lazy
ether/src/Control/Monad/Ether/Implicit/State/Lazy.hsnew file+84
@@ -0,0 +1,84 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+
3+-- | See "Control.Monad.Ether.State.Lazy".
4+
5+module Control.Monad.Ether.Implicit.State.Lazy
6+ (
7+ -- * MonadState class
8+ MonadState
9+ , get
10+ , put
11+ , state
12+ , modify
13+ , gets
14+ -- * The State monad
15+ , State
16+ , runState
17+ , evalState
18+ , execState
19+ -- * The StateT monad transformer
20+ , StateT
21+ , stateT
22+ , runStateT
23+ , evalStateT
24+ , execStateT
25+ ) where
26+
27+import qualified Control.Monad.Ether.State.Lazy as A
28+
29+-- | See 'Control.Monad.Ether.State.Lazy.StateT'.
30+type StateT s = A.StateT s s
31+
32+-- | See 'Control.Monad.Ether.State.Lazy.stateT'.
33+stateT :: (s -> m (a, s)) -> StateT s m a
34+stateT = A.stateT
35+
36+-- | See 'Control.Monad.Ether.State.Lazy.runStateT'.
37+runStateT :: StateT s m a -> s -> m (a, s)
38+runStateT = A.runStateT
39+
40+-- | See 'Control.Monad.Ether.State.Lazy.runState'.
41+runState :: State s a -> s -> (a, s)
42+runState = A.runState
43+
44+-- | See 'Control.Monad.Ether.State.Lazy.evalStateT'.
45+evalStateT :: Monad m => StateT s m a -> s -> m a
46+evalStateT = A.evalStateT
47+
48+-- | See 'Control.Monad.Ether.State.Lazy.State'.
49+type State s = A.State s s
50+
51+-- | See 'Control.Monad.Ether.State.Lazy.evalState'.
52+evalState :: State s a -> s -> a
53+evalState = A.evalState
54+
55+-- | See 'Control.Monad.Ether.State.Lazy.execStateT'.
56+execStateT :: Monad m => StateT s m a -> s -> m s
57+execStateT = A.execStateT
58+
59+-- | See 'Control.Monad.Ether.State.Lazy.execState'.
60+execState :: State s a -> s -> s
61+execState = A.execState
62+
63+-- | See 'Control.Monad.Ether.State.Lazy.MonadState'.
64+type MonadState s = A.MonadState s s
65+
66+-- | See 'Control.Monad.Ether.State.Lazy.get'.
67+get :: forall s m . MonadState s m => m s
68+get = A.get @s
69+
70+-- | See 'Control.Monad.Ether.State.Lazy.gets'.
71+gets :: forall s m a . MonadState s m => (s -> a) -> m a
72+gets = A.gets @s
73+
74+-- | See 'Control.Monad.Ether.State.Lazy.put'.
75+put :: forall s m . MonadState s m => s -> m ()
76+put = A.put @s
77+
78+-- | See 'Control.Monad.Ether.State.Lazy.state'.
79+state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
80+state = A.state @s
81+
82+-- | See 'Control.Monad.Ether.State.Lazy.modify'.
83+modify :: forall s m . MonadState s m => (s -> s) -> m ()
84+modify = A.modify @s
ether/src/Control/Monad/Ether/Implicit/State/Strict.hsnew file+84
@@ -0,0 +1,84 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+
3+-- | See "Control.Monad.Ether.State.Strict".
4+
5+module Control.Monad.Ether.Implicit.State.Strict
6+ (
7+ -- * MonadState class
8+ MonadState
9+ , get
10+ , put
11+ , state
12+ , modify
13+ , gets
14+ -- * The State monad
15+ , State
16+ , runState
17+ , evalState
18+ , execState
19+ -- * The StateT monad transformer
20+ , StateT
21+ , stateT
22+ , runStateT
23+ , evalStateT
24+ , execStateT
25+ ) where
26+
27+import qualified Control.Monad.Ether.State.Strict as A
28+
29+-- | See 'Control.Monad.Ether.State.Strict.StateT'.
30+type StateT s = A.StateT s s
31+
32+-- | See 'Control.Monad.Ether.State.Strict.stateT'.
33+stateT :: (s -> m (a, s)) -> StateT s m a
34+stateT = A.stateT
35+
36+-- | See 'Control.Monad.Ether.State.Strict.runStateT'.
37+runStateT :: StateT s m a -> s -> m (a, s)
38+runStateT = A.runStateT
39+
40+-- | See 'Control.Monad.Ether.State.Strict.runState'.
41+runState :: State s a -> s -> (a, s)
42+runState = A.runState
43+
44+-- | See 'Control.Monad.Ether.State.Strict.evalStateT'.
45+evalStateT :: Monad m => StateT s m a -> s -> m a
46+evalStateT = A.evalStateT
47+
48+-- | See 'Control.Monad.Ether.State.Strict.State'.
49+type State s = A.State s s
50+
51+-- | See 'Control.Monad.Ether.State.Strict.evalState'.
52+evalState :: State s a -> s -> a
53+evalState = A.evalState
54+
55+-- | See 'Control.Monad.Ether.State.Strict.execStateT'.
56+execStateT :: Monad m => StateT s m a -> s -> m s
57+execStateT = A.execStateT
58+
59+-- | See 'Control.Monad.Ether.State.Strict.execState'.
60+execState :: State s a -> s -> s
61+execState = A.execState
62+
63+-- | See 'Control.Monad.Ether.State.Strict.MonadState'.
64+type MonadState s = A.MonadState s s
65+
66+-- | See 'Control.Monad.Ether.State.Strict.get'.
67+get :: forall s m . MonadState s m => m s
68+get = A.get @s
69+
70+-- | See 'Control.Monad.Ether.State.Strict.gets'.
71+gets :: forall s m a . MonadState s m => (s -> a) -> m a
72+gets = A.gets @s
73+
74+-- | See 'Control.Monad.Ether.State.Strict.put'.
75+put :: forall s m . MonadState s m => s -> m ()
76+put = A.put @s
77+
78+-- | See 'Control.Monad.Ether.State.Strict.state'.
79+state :: forall s m a . MonadState s m => (s -> (a, s)) -> m a
80+state = A.state @s
81+
82+-- | See 'Control.Monad.Ether.State.Strict.modify'.
83+modify :: forall s m . MonadState s m => (s -> s) -> m ()
84+modify = A.modify @s
ether/src/Control/Monad/Ether/Implicit/Writer.hsnew file+79
@@ -0,0 +1,79 @@
1+{-# LANGUAGE ConstraintKinds #-}
2+
3+-- | See "Control.Monad.Ether.Writer".
4+
5+module Control.Monad.Ether.Implicit.Writer
6+ (
7+ -- * MonadWriter class
8+ MonadWriter
9+ , writer
10+ , tell
11+ , listen
12+ , pass
13+ , listens
14+ , censor
15+ -- * The Writer monad
16+ , Writer
17+ , runWriter
18+ , execWriter
19+ -- * The WriterT monad transformer
20+ , WriterT
21+ , writerT
22+ , runWriterT
23+ , execWriterT
24+ ) where
25+
26+import qualified Control.Monad.Ether.Writer as A
27+
28+-- | See 'Control.Monad.Ether.Writer.MonadWriter'.
29+type MonadWriter w = A.MonadWriter w w
30+
31+-- | See 'Control.Monad.Ether.Writer.writer'.
32+writer :: forall w m a . MonadWriter w m => (a, w) -> m a
33+writer = A.writer @w
34+
35+-- | See 'Control.Monad.Ether.Writer.tell'.
36+tell :: forall w m . MonadWriter w m => w -> m ()
37+tell = A.tell @w
38+
39+-- | See 'Control.Monad.Ether.Writer.listen'.
40+listen :: forall w m a . MonadWriter w m => m a -> m (a, w)
41+listen = A.listen @w
42+
43+-- | See 'Control.Monad.Ether.Writer.pass'.
44+pass :: forall w m a . MonadWriter w m => m (a, w -> w) -> m a
45+pass = A.pass @w
46+
47+-- | See 'Control.Monad.Ether.Writer.listens'.
48+listens :: forall w m a b . MonadWriter w m => (w -> b) -> m a -> m (a, b)
49+listens = A.listens @w
50+
51+-- | See 'Control.Monad.Ether.Writer.censor'.
52+censor :: forall w m a . MonadWriter w m => (w -> w) -> m a -> m a
53+censor = A.censor @w
54+
55+-- | See 'Control.Monad.Ether.Writer.Writer'.
56+type Writer w = A.Writer w w
57+
58+-- | See 'Control.Monad.Ether.Writer.runWriter'.
59+runWriter :: Writer w a -> (a, w)
60+runWriter = A.runWriter
61+
62+-- | See 'Control.Monad.Ether.Writer.execWriter'.
63+execWriter :: Writer w a -> w
64+execWriter = A.execWriter
65+
66+-- | See 'Control.Monad.Ether.Writer.WriterT'.
67+type WriterT w = A.WriterT w w
68+
69+-- | See 'Control.Monad.Ether.Writer.writerT'.
70+writerT :: m (a, w) -> WriterT w m a
71+writerT = A.writerT
72+
73+-- | See 'Control.Monad.Ether.Writer.runWriterT'.
74+runWriterT :: WriterT w m a -> m (a, w)
75+runWriterT = A.runWriterT
76+
77+-- | See 'Control.Monad.Ether.Writer.execWriterT'.
78+execWriterT :: Monad m => WriterT w m a -> m w
79+execWriterT = A.execWriterT
ether/src/Control/Monad/Ether/Reader.hsnew file+96
@@ -0,0 +1,96 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE UndecidableInstances #-}
4+{-# LANGUAGE TypeFamilies #-}
5+{-# LANGUAGE AllowAmbiguousTypes #-}
6+
7+-- | See "Control.Monad.Reader".
8+
9+module Control.Monad.Ether.Reader
10+ (
11+ -- * MonadReader class
12+ MonadReader
13+ , ask
14+ , local
15+ , reader
16+ , asks
17+ -- * The Reader monad
18+ , Reader
19+ , runReader
20+ -- * The ReaderT monad transformer
21+ , ReaderT
22+ , readerT
23+ , runReaderT
24+ ) where
25+
26+import Control.Monad.Ether.Reader.Class
27+import qualified Control.Monad.Trans.Ether.Handler as D
28+import Control.Monad.Trans.Lift.Local (Local)
29+import qualified Control.Monad.Reader as T
30+import Data.Functor.Identity
31+import Data.Coerce
32+
33+-- | Retrieves a function of the current environment.
34+asks
35+ :: forall tag r m a
36+ . MonadReader tag r m
37+ => (r -> a)
38+ -- ^ The selector function to apply to the environment.
39+ -> m a
40+asks = reader @tag
41+{-# INLINE asks #-}
42+
43+-- | Encode type-level information for 'ReaderT'.
44+data READER
45+
46+-- | The parameterizable reader monad.
47+--
48+-- Computations are functions of a shared environment.
49+--
50+-- The 'return' function ignores the environment, while '>>=' passes
51+-- the inherited environment to both subcomputations.
52+type Reader tag r = ReaderT tag r Identity
53+
54+-- | The reader monad transformer,
55+-- which adds a read-only environment to the given monad.
56+--
57+-- The 'return' function ignores the environment, while '>>=' passes
58+-- the inherited environment to both subcomputations.
59+type ReaderT tag r = D.Handler '(READER, tag) (T.ReaderT r)
60+
61+-- | Constructor for computations in the reader monad transformer.
62+readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
63+readerT = coerce (T.ReaderT @r @m @a)
64+{-# INLINE readerT #-}
65+
66+-- | Runs a 'ReaderT' with the given environment
67+-- and returns the final value.
68+runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
69+runReaderT = coerce (T.runReaderT @r @_ @m @a)
70+{-# INLINE runReaderT #-}
71+
72+-- | Runs a 'ReaderT' with the given environment
73+-- and returns the final value.
74+runReader :: forall tag r a . Reader tag r a -> r -> a
75+runReader = coerce (T.runReader @r @a)
76+{-# INLINE runReader #-}
77+
78+instance
79+ ( T.MonadReader r (trans m) -- FIXME: (forall m . T.MonadReader r (trans m))
80+ -- otherwise we can leak a MonadReader instance
81+ -- from 'm'
82+ ) => MonadReader tag r (D.Handler '(READER, tag) trans (m :: * -> *))
83+ where
84+
85+ ask = coerce (T.ask @r @(trans m))
86+ {-# INLINE ask #-}
87+
88+ local =
89+ coerce (T.local @r @(trans m) @a) ::
90+ forall dp a . Local r (D.Handler dp trans m) a
91+ {-# INLINE local #-}
92+
93+ reader =
94+ coerce (T.reader @r @(trans m) @a) ::
95+ forall dp a . (r -> a) -> D.Handler dp trans m a
96+ {-# INLINE reader #-}
ether/src/Control/Monad/Ether/Reader/Class.hsnew file+69
@@ -0,0 +1,69 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE UndecidableInstances #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE DataKinds #-}
6+{-# LANGUAGE AllowAmbiguousTypes #-}
7+
8+-- | See "Control.Monad.Reader.Class".
9+
10+module Control.Monad.Ether.Reader.Class
11+ ( MonadReader(..)
12+ ) where
13+
14+import Control.Monad.Trans.Ether.Handler
15+import qualified Control.Monad.Trans.Lift.Local as Lift
16+import Data.Coerce
17+
18+-- | See 'Control.Monad.Reader.MonadReader'.
19+class Monad m => MonadReader tag r m | m tag -> r where
20+
21+ {-# MINIMAL (ask | reader), local #-}
22+
23+ -- | Retrieves the monad environment.
24+ ask :: m r
25+ ask = reader @tag id
26+
27+ -- | Executes a computation in a modified environment.
28+ local
29+ :: (r -> r)
30+ -- ^ The function to modify the environment.
31+ -> m a
32+ -- ^ @Reader@ to run in the modified environment.
33+ -> m a
34+
35+ -- | Retrieves a function of the current environment.
36+ reader
37+ :: (r -> a)
38+ -- ^ The selector function to apply to the environment.
39+ -> m a
40+ reader f = fmap f (ask @tag)
41+
42+instance {-# OVERLAPPABLE #-}
43+ ( Lift.LiftLocal t
44+ , Monad (t m)
45+ , MonadReader tag r m
46+ ) => MonadReader tag r (t m)
47+ where
48+ ask = Lift.lift (ask @tag)
49+ local = Lift.liftLocal (ask @tag) (local @tag)
50+
51+instance {-# OVERLAPPABLE #-}
52+ ( Monad (trans m)
53+ , MonadReader tag r (Handler dps trans m)
54+ ) => MonadReader tag r (Handler (dp ': dps) trans (m :: * -> *))
55+ where
56+
57+ ask =
58+ (coerce ::
59+ Handler dps trans m r ->
60+ Handler (dp ': dps) trans m r)
61+ (ask @tag)
62+ {-# INLINE ask #-}
63+
64+ local =
65+ (coerce :: forall a .
66+ Lift.Local r (Handler dps trans m) a ->
67+ Lift.Local r (Handler (dp ': dps) trans m) a)
68+ (local @tag)
69+ {-# INLINE local #-}
ether/src/Control/Monad/Ether/State.hsnew file+7
@@ -0,0 +1,7 @@
1+-- | See "Control.Monad.State".
2+
3+module Control.Monad.Ether.State
4+ ( module Control.Monad.Ether.State.Lazy
5+ ) where
6+
7+import Control.Monad.Ether.State.Lazy
ether/src/Control/Monad/Ether/State/Class.hsnew file+74
@@ -0,0 +1,74 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE UndecidableInstances #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE DataKinds #-}
6+{-# LANGUAGE AllowAmbiguousTypes #-}
7+
8+-- | See "Control.Monad.State.Class".
9+
10+module Control.Monad.Ether.State.Class
11+ ( MonadState(..)
12+ ) where
13+
14+import Control.Monad.Trans.Ether.Handler
15+import qualified Control.Monad.Trans as Lift
16+import Data.Coerce
17+
18+-- | See 'Control.Monad.State.MonadState'.
19+class Monad m => MonadState tag s m | m tag -> s where
20+
21+ {-# MINIMAL state | get, put #-}
22+
23+ -- | Return the state from the internals of the monad.
24+ get :: m s
25+ get = state @tag (\s -> (s, s))
26+
27+ -- | Replace the state inside the monad.
28+ put :: s -> m ()
29+ put s = state @tag (\_ -> ((), s))
30+
31+ -- | Embed a simple state action into the monad.
32+ state :: (s -> (a, s)) -> m a
33+ state f = do
34+ s <- get @tag
35+ let ~(a, s') = f s
36+ put @tag s'
37+ return a
38+
39+instance {-# OVERLAPPABLE #-}
40+ ( Lift.MonadTrans t
41+ , Monad (t m)
42+ , MonadState tag s m
43+ ) => MonadState tag s (t m)
44+ where
45+ get = Lift.lift (get @tag)
46+ put = Lift.lift . put @tag
47+ state = Lift.lift . state @tag
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 :: * -> *))
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.hsnew file+48
@@ -0,0 +1,48 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE AllowAmbiguousTypes #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE UndecidableInstances #-}
5+
6+module Control.Monad.Ether.State.Common
7+ ( MonadState
8+ , get
9+ , put
10+ , state
11+ , modify
12+ , gets
13+ , STATE
14+ ) where
15+
16+import Control.Monad.Ether.State.Class
17+import qualified Control.Monad.State as T
18+import qualified Control.Monad.Trans.Ether.Handler as D
19+import Data.Coerce
20+
21+-- | Encode type-level information for 'StateT'.
22+data STATE
23+
24+-- | Modifies the state inside a state monad.
25+modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
26+modify f = state @tag (\s -> ((), f s))
27+{-# INLINABLE modify #-}
28+
29+-- | Gets specific component of the state, using a projection function supplied.
30+gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
31+gets f = fmap f (get @tag)
32+{-# INLINABLE gets #-}
33+
34+instance
35+ ( T.MonadState s (trans m) -- FIXME: (forall m . T.MonadState s (trans m))
36+ ) => MonadState tag s (D.Handler '(STATE, tag) trans (m :: * -> *))
37+ where
38+
39+ get = coerce (T.get @s @(trans m))
40+ {-# INLINE get #-}
41+
42+ put = coerce (T.put @s @(trans m))
43+ {-# INLINE put #-}
44+
45+ state =
46+ coerce (T.state @s @(trans m) @a) ::
47+ forall dp a . (s -> (a, s)) -> D.Handler dp trans m a
48+ {-# INLINE state #-}
ether/src/Control/Monad/Ether/State/Lazy.hsnew file+89
@@ -0,0 +1,89 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE UndecidableInstances #-}
4+{-# LANGUAGE TypeFamilies #-}
5+
6+-- | See "Control.Monad.State.Lazy".
7+
8+module Control.Monad.Ether.State.Lazy
9+ (
10+ -- * MonadState class
11+ MonadState
12+ , get
13+ , put
14+ , state
15+ , modify
16+ , gets
17+ -- * The State monad
18+ , State
19+ , runState
20+ , evalState
21+ , execState
22+ -- * The StateT monad transformer
23+ , StateT
24+ , stateT
25+ , runStateT
26+ , evalStateT
27+ , execStateT
28+ ) where
29+
30+import Control.Monad.Ether.State.Common
31+import qualified Control.Monad.Trans.Ether.Handler as D
32+import qualified Control.Monad.Trans.State.Lazy as T
33+import Data.Functor.Identity
34+import Data.Coerce
35+
36+-- | The parametrizable state monad.
37+--
38+-- Computations have access to a mutable state.
39+--
40+-- The 'return' function leaves the state unchanged, while '>>=' uses
41+-- the final state of the first computation as the initial state of the second.
42+type State tag r = StateT tag r Identity
43+
44+-- | The state monad transformer.
45+--
46+-- The 'return' function leaves the state unchanged, while '>>=' uses
47+-- the final state of the first computation as the initial state of the second.
48+type StateT tag s = D.Handler '(STATE, tag) (T.StateT s)
49+
50+-- | Constructor for computations in the state monad transformer.
51+stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
52+stateT = coerce (T.StateT @s @m @a)
53+{-# INLINE stateT #-}
54+
55+-- | Runs a 'StateT' with the given initial state
56+-- and returns both the final value and the final state.
57+runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
58+runStateT = coerce (T.runStateT @s @m @a)
59+{-# INLINE runStateT #-}
60+
61+-- | Runs a 'StateT' with the given initial state
62+-- and returns the final value, discarding the final state.
63+evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
64+evalStateT = coerce (T.evalStateT @m @s @a)
65+{-# INLINE evalStateT #-}
66+
67+-- | Runs a 'StateT' with the given initial state
68+-- and returns the final state, discarding the final value.
69+execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
70+execStateT = coerce (T.execStateT @m @s @a)
71+{-# INLINE execStateT #-}
72+
73+-- | Runs a 'State' with the given initial state
74+-- and returns both the final value and the final state.
75+runState :: forall tag s a . State tag s a -> s -> (a, s)
76+runState = coerce (T.runState @s @a)
77+{-# INLINE runState #-}
78+
79+-- | Runs a 'State' with the given initial state
80+-- and returns the final value, discarding the final state.
81+evalState :: forall tag s a . State tag s a -> s -> a
82+evalState = coerce (T.evalState @s @a)
83+{-# INLINE evalState #-}
84+
85+-- | Runs a 'State' with the given initial state
86+-- and returns the final state, discarding the final value.
87+execState :: forall tag s a . State tag s a -> s -> s
88+execState = coerce (T.execState @s @a)
89+{-# INLINE execState #-}
ether/src/Control/Monad/Ether/State/Strict.hsnew file+89
@@ -0,0 +1,89 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE UndecidableInstances #-}
4+{-# LANGUAGE TypeFamilies #-}
5+
6+-- | See "Control.Monad.State.Strict".
7+
8+module Control.Monad.Ether.State.Strict
9+ (
10+ -- * MonadState class
11+ MonadState
12+ , get
13+ , put
14+ , state
15+ , modify
16+ , gets
17+ -- * The State monad
18+ , State
19+ , runState
20+ , evalState
21+ , execState
22+ -- * The StateT monad transformer
23+ , StateT
24+ , stateT
25+ , runStateT
26+ , evalStateT
27+ , execStateT
28+ ) where
29+
30+import Control.Monad.Ether.State.Common
31+import qualified Control.Monad.Trans.Ether.Handler as D
32+import qualified Control.Monad.Trans.State.Strict as T
33+import Data.Functor.Identity
34+import Data.Coerce
35+
36+-- | The parametrizable state monad.
37+--
38+-- Computations have access to a mutable state.
39+--
40+-- The 'return' function leaves the state unchanged, while '>>=' uses
41+-- the final state of the first computation as the initial state of the second.
42+type State tag r = StateT tag r Identity
43+
44+-- | The state monad transformer.
45+--
46+-- The 'return' function leaves the state unchanged, while '>>=' uses
47+-- the final state of the first computation as the initial state of the second.
48+type StateT tag s = D.Handler '(STATE, tag) (T.StateT s)
49+
50+-- | Constructor for computations in the state monad transformer.
51+stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
52+stateT = coerce (T.StateT @s @m @a)
53+{-# INLINE stateT #-}
54+
55+-- | Runs a 'StateT' with the given initial state
56+-- and returns both the final value and the final state.
57+runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
58+runStateT = coerce (T.runStateT @s @m @a)
59+{-# INLINE runStateT #-}
60+
61+-- | Runs a 'StateT' with the given initial state
62+-- and returns the final value, discarding the final state.
63+evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
64+evalStateT = coerce (T.evalStateT @m @s @a)
65+{-# INLINE evalStateT #-}
66+
67+-- | Runs a 'StateT' with the given initial state
68+-- and returns the final state, discarding the final value.
69+execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
70+execStateT = coerce (T.execStateT @m @s @a)
71+{-# INLINE execStateT #-}
72+
73+-- | Runs a 'State' with the given initial state
74+-- and returns both the final value and the final state.
75+runState :: forall tag s a . State tag s a -> s -> (a, s)
76+runState = coerce (T.runState @s @a)
77+{-# INLINE runState #-}
78+
79+-- | Runs a 'State' with the given initial state
80+-- and returns the final value, discarding the final state.
81+evalState :: forall tag s a . State tag s a -> s -> a
82+evalState = coerce (T.evalState @s @a)
83+{-# INLINE evalState #-}
84+
85+-- | Runs a 'State' with the given initial state
86+-- and returns the final state, discarding the final value.
87+execState :: forall tag s a . State tag s a -> s -> s
88+execState = coerce (T.execState @s @a)
89+{-# INLINE execState #-}
ether/src/Control/Monad/Ether/TagAttach.hsnew file+73
@@ -0,0 +1,73 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE UndecidableInstances #-}
5+{-# LANGUAGE DataKinds #-}
6+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+
8+module Control.Monad.Ether.TagAttach
9+ ( TAG_ATTACH
10+ , TagAttachT
11+ , tagAttach
12+ ) where
13+
14+import Control.Monad.Trans.Identity
15+
16+import Control.Monad.Ether.Reader.Class
17+import Control.Monad.Ether.State.Class
18+import Control.Monad.Ether.Except.Class
19+import Control.Monad.Ether.Writer.Class
20+
21+import Control.Monad.Ether.Reader as A
22+import Control.Monad.Ether.State.Common as A
23+import Control.Monad.Ether.Except as A
24+import Control.Monad.Ether.Writer as A
25+
26+import qualified Control.Monad.Reader.Class as Class
27+import qualified Control.Monad.State.Class as Class
28+import qualified Control.Monad.Writer.Class as Class
29+import qualified Control.Monad.Error.Class as Class
30+
31+import Control.Monad.Trans.Ether.Handler
32+
33+import Data.Coerce
34+
35+-- | Encode type-level information for 'tagAttach'.
36+data TAG_ATTACH t
37+
38+type TagAttachT t = Handler (TAG_ATTACH t) IdentityT
39+
40+-- | Attach a tag to untagged transformers.
41+tagAttach :: forall tag m a . TagAttachT tag m a -> m a
42+tagAttach = coerce (runIdentityT @_ @m @a)
43+{-# INLINE tagAttach #-}
44+
45+instance
46+ ( MonadReader tag r m, trans ~ IdentityT
47+ ) => Class.MonadReader r (Handler (TAG_ATTACH tag) trans m)
48+ where
49+ ask = A.ask @tag
50+ local = A.local @tag
51+
52+instance
53+ ( MonadState tag s m, trans ~ IdentityT
54+ ) => Class.MonadState s (Handler (TAG_ATTACH tag) trans m)
55+ where
56+ get = A.get @tag
57+ put = A.put @tag
58+
59+instance
60+ ( MonadExcept tag e m, trans ~ IdentityT
61+ ) => Class.MonadError e (Handler (TAG_ATTACH tag) trans m)
62+ where
63+ throwError = A.throw @tag
64+ catchError = A.catch @tag
65+
66+instance
67+ ( MonadWriter tag w m, trans ~ IdentityT
68+ ) => Class.MonadWriter w (Handler (TAG_ATTACH tag) trans m)
69+ where
70+ writer = A.writer @tag
71+ tell = A.tell @tag
72+ listen = A.listen @tag
73+ pass = A.pass @tag
ether/src/Control/Monad/Ether/TagReplace.hsnew file+68
@@ -0,0 +1,68 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE TypeFamilies #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE UndecidableInstances #-}
5+{-# LANGUAGE DataKinds #-}
6+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7+
8+module Control.Monad.Ether.TagReplace
9+ ( TAG_REPLACE
10+ , TagReplaceT
11+ , tagReplace
12+ ) where
13+
14+import Control.Monad.Trans.Identity
15+
16+import Control.Monad.Ether.Reader.Class
17+import Control.Monad.Ether.State.Class
18+import Control.Monad.Ether.Except.Class
19+import Control.Monad.Ether.Writer.Class
20+
21+import Control.Monad.Ether.Reader as A
22+import Control.Monad.Ether.State.Common as A
23+import Control.Monad.Ether.Except as A
24+import Control.Monad.Ether.Writer as A
25+
26+import Control.Monad.Trans.Ether.Handler
27+
28+import Data.Coerce
29+
30+-- | Encode type-level information for 'tagReplace'.
31+data TAG_REPLACE tOld tNew
32+
33+type TagReplaceT tOld tNew = Handler (TAG_REPLACE tOld tNew) IdentityT
34+
35+-- | Replace a tag with another tag.
36+tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
37+tagReplace = coerce (runIdentityT @_ @m @a)
38+{-# INLINE tagReplace #-}
39+
40+instance
41+ ( MonadReader tNew r m, trans ~ IdentityT
42+ ) => MonadReader tOld r (Handler (TAG_REPLACE tOld tNew) trans m)
43+ where
44+ ask = A.ask @tNew
45+ local = A.local @tNew
46+
47+instance
48+ ( MonadState tNew s m, trans ~ IdentityT
49+ ) => MonadState tOld s (Handler (TAG_REPLACE tOld tNew) trans m)
50+ where
51+ get = A.get @tNew
52+ put = A.put @tNew
53+
54+instance
55+ ( MonadExcept tNew e m, trans ~ IdentityT
56+ ) => MonadExcept tOld e (Handler (TAG_REPLACE tOld tNew) trans m)
57+ where
58+ throw = A.throw @tNew
59+ catch = A.catch @tNew
60+
61+instance
62+ ( MonadWriter tNew w m, trans ~ IdentityT
63+ ) => MonadWriter tOld w (Handler (TAG_REPLACE tOld tNew) trans m)
64+ where
65+ writer = A.writer @tNew
66+ tell = A.tell @tNew
67+ listen = A.listen @tNew
68+ pass = A.pass @tNew
ether/src/Control/Monad/Ether/Writer.hsnew file+112
@@ -0,0 +1,112 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE FlexibleInstances #-}
3+{-# LANGUAGE UndecidableInstances #-}
4+{-# LANGUAGE TypeFamilies #-}
5+{-# LANGUAGE AllowAmbiguousTypes #-}
6+
7+-- | See "Control.Monad.Writer".
8+
9+module Control.Monad.Ether.Writer
10+ (
11+ -- * MonadWriter class
12+ MonadWriter
13+ , writer
14+ , tell
15+ , listen
16+ , pass
17+ , listens
18+ , censor
19+ -- * The Writer monad
20+ , Writer
21+ , runWriter
22+ , execWriter
23+ -- * The WriterT monad transformer
24+ , WriterT
25+ , writerT
26+ , runWriterT
27+ , execWriterT
28+ ) where
29+
30+import Control.Monad.Ether.Writer.Class
31+import qualified Control.Monad.Trans.Ether.Handler as D
32+import qualified Control.Monad.Writer as T
33+import Data.Functor.Identity
34+import Control.Monad.Signatures (Listen, Pass)
35+import Data.Coerce
36+
37+-- | Execute an action and add the result of applying the given function to
38+-- its accumulator to the value of the computation.
39+listens :: forall tag w m a b . MonadWriter tag w m => (w -> b) -> m a -> m (a, b)
40+listens f m = do
41+ ~(a, w) <- listen @tag m
42+ return (a, f w)
43+
44+-- | Execute an action and apply a function to its accumulator.
45+censor :: forall tag w m a . MonadWriter tag w m => (w -> w) -> m a -> m a
46+censor f m = pass @tag $ do
47+ a <- m
48+ return (a, f)
49+
50+-- | Encode type-level information for 'WriterT'.
51+data WRITER
52+
53+-- | The parametrizable writer monad.
54+--
55+-- Computations can accumulate a monoid value.
56+--
57+-- The 'return' function produces the output 'mempty', while '>>=' combines
58+-- the outputs of the subcomputations using 'mappend'.
59+type Writer tag w = WriterT tag w Identity
60+
61+-- | The writer monad transformer.
62+--
63+-- The 'return' function produces the output 'mempty', while '>>=' combines
64+-- the outputs of the subcomputations using 'mappend'.
65+type WriterT tag w = D.Handler '(WRITER, tag) (T.WriterT w)
66+
67+-- | Constructor for computations in the writer monad transformer.
68+writerT :: forall tag w m a . m (a, w) -> WriterT tag w m a
69+writerT = coerce (T.WriterT @w @m @a)
70+
71+-- | Runs a 'WriterT' and returns both the normal value
72+-- and the final accumulator.
73+runWriterT :: forall tag w m a . WriterT tag w m a -> m (a, w)
74+runWriterT = coerce (T.runWriterT @w @m @a)
75+
76+-- | Runs a 'Writer' and returns both the normal value
77+-- and the final accumulator.
78+runWriter :: forall tag w a . Writer tag w a -> (a, w)
79+runWriter = coerce (T.runWriter @w @a)
80+
81+-- | Runs a 'WriterT' and returns the final accumulator,
82+-- discarding the normal value.
83+execWriterT :: forall tag w m a . Monad m => WriterT tag w m a -> m w
84+execWriterT = coerce (T.execWriterT @m @w @a)
85+
86+-- | Runs a 'Writer' and returns the final accumulator,
87+-- discarding the normal value.
88+execWriter :: forall tag w a . Writer tag w a -> w
89+execWriter = coerce (T.execWriter @w @a)
90+
91+instance
92+ ( T.MonadWriter w (trans m) -- FIXME: (forall m . T.MonadWriter w (trans m))
93+ ) => MonadWriter tag w (D.Handler '(WRITER, tag) trans (m :: * -> *))
94+ where
95+
96+ writer =
97+ coerce (T.writer @w @(trans m) @a) ::
98+ forall dp a . (a, w) -> D.Handler dp trans m a
99+ {-# INLINE writer #-}
100+
101+ tell = coerce (T.tell @w @(trans m))
102+ {-# INLINE tell #-}
103+
104+ listen =
105+ coerce (T.listen @w @(trans m) @a) ::
106+ forall dp a . Listen w (D.Handler dp trans m) a
107+ {-# INLINE listen #-}
108+
109+ pass =
110+ coerce (T.pass @w @(trans m) @a) ::
111+ forall dp a . Pass w (D.Handler dp trans m) a
112+ {-# INLINE pass #-}
ether/src/Control/Monad/Ether/Writer/Class.hsnew file+48
@@ -0,0 +1,48 @@
1+{-# LANGUAGE FlexibleInstances #-}
2+{-# LANGUAGE UndecidableInstances #-}
3+{-# LANGUAGE TypeFamilies #-}
4+{-# LANGUAGE AllowAmbiguousTypes #-}
5+
6+-- | See "Control.Monad.Writer.Class".
7+
8+module Control.Monad.Ether.Writer.Class
9+ ( MonadWriter(..)
10+ ) where
11+
12+import qualified Control.Monad.Trans.Lift.Listen as Lift
13+import qualified Control.Monad.Trans.Lift.Pass as Lift
14+
15+-- | See 'Control.Monad.Writer.MonadWriter'.
16+class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
17+
18+ {-# MINIMAL (writer | tell), listen, pass #-}
19+
20+ -- | Embed a simple writer action.
21+ writer :: (a, w) -> m a
22+ writer ~(a, w) = do
23+ tell @tag w
24+ return a
25+
26+ -- | Append a value to the accumulator within the monad.
27+ tell :: w -> m ()
28+ tell w = writer @tag ((),w)
29+
30+ -- | Execute an action and add its accumulator
31+ -- to the value of the computation.
32+ listen :: m a -> m (a, w)
33+
34+ -- | Execute an action which returns a value and a function,
35+ -- and return the value, applying the function to the accumulator.
36+ pass :: m (a, w -> w) -> m a
37+
38+instance {-# OVERLAPPABLE #-}
39+ ( Lift.LiftListen t
40+ , Lift.LiftPass t
41+ , Monad (t m)
42+ , MonadWriter tag w m
43+ , Monoid w
44+ ) => MonadWriter tag w (t m) where
45+ writer = Lift.lift . writer @tag
46+ tell = Lift.lift . tell @tag
47+ listen = Lift.liftListen (listen @tag)
48+ pass = Lift.liftPass (pass @tag)
ether/src/Control/Monad/Trans/Ether/Handler.hsnew file+186
@@ -0,0 +1,186 @@
1+{-# LANGUAGE DeriveGeneric #-}
2+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE UndecidableInstances #-}
5+{-# LANGUAGE ConstraintKinds #-}
6+{-# LANGUAGE RankNTypes #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+
10+module Control.Monad.Trans.Ether.Handler
11+ ( Handler(..)
12+ ) where
13+
14+import Control.Applicative
15+import Control.Monad (MonadPlus)
16+import Control.Monad.Fix (MonadFix)
17+import Control.Monad.Trans.Class (MonadTrans, lift)
18+import Control.Monad.IO.Class (MonadIO)
19+import Control.Monad.Morph (MFunctor, MMonad)
20+import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
21+
22+import qualified Control.Monad.Base as MB
23+import qualified Control.Monad.Trans.Control as MC
24+
25+import qualified Control.Monad.Trans.Lift.StT as Lift
26+import qualified Control.Monad.Trans.Lift.Local as Lift
27+import qualified Control.Monad.Trans.Lift.Catch as Lift
28+import qualified Control.Monad.Trans.Lift.Listen as Lift
29+import qualified Control.Monad.Trans.Lift.Pass as Lift
30+import qualified Control.Monad.Trans.Lift.CallCC as Lift
31+
32+import qualified Control.Monad.Cont.Class as Class
33+import qualified Control.Monad.Reader.Class as Class
34+import qualified Control.Monad.State.Class as Class
35+import qualified Control.Monad.Writer.Class as Class
36+import qualified Control.Monad.Error.Class as Class
37+
38+import GHC.Generics (Generic)
39+import Data.Coerce (coerce)
40+
41+newtype Handler dp trans m a = Handler (trans m a)
42+ deriving
43+ ( Generic
44+ , Functor, Applicative, Alternative, Monad, MonadPlus
45+ , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
46+ , MonadThrow, MonadCatch, MonadMask )
47+
48+type Pack dp trans m a = trans m a -> Handler dp trans m a
49+
50+type Unpack dp trans m a = Handler dp trans m a -> trans m a
51+
52+instance
53+ ( MB.MonadBase b (trans m)
54+ ) => MB.MonadBase b (Handler dp trans m)
55+ where
56+ liftBase =
57+ (coerce :: forall a .
58+ (b a -> trans m a) ->
59+ (b a -> Handler dp trans m a))
60+ MB.liftBase
61+
62+instance
63+ ( MC.MonadTransControl trans
64+ ) => MC.MonadTransControl (Handler dp trans)
65+ where
66+ type StT (Handler dp trans) a = MC.StT trans a
67+ liftWith = MC.defaultLiftWith
68+ (coerce :: Pack dp trans m a)
69+ (coerce :: Unpack dp trans m a)
70+ restoreT = MC.defaultRestoreT
71+ (coerce :: Pack dp trans m a)
72+
73+type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
74+
75+newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
76+
77+coerceLiftBaseWith ::
78+ LiftBaseWith b (trans m) a ->
79+ LiftBaseWith b (Handler dp trans m) a
80+coerceLiftBaseWith lbw =
81+ unLBW (coerce (LBW lbw))
82+{-# INLINE coerceLiftBaseWith #-}
83+
84+instance
85+ ( MC.MonadBaseControl b (trans m)
86+ ) => MC.MonadBaseControl b (Handler dp trans m)
87+ where
88+ type StM (Handler dp trans m) a = MC.StM (trans m) a
89+
90+ liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
91+ {-# INLINE liftBaseWith #-}
92+
93+ restoreM =
94+ (coerce :: forall a .
95+ (MC.StM (trans m) a -> trans m a) ->
96+ (MC.StM (trans m) a -> Handler dp trans m a))
97+ MC.restoreM
98+ {-# INLINE restoreM #-}
99+
100+type instance Lift.StT (Handler dp trans) a = Lift.StT trans a
101+
102+instance Lift.LiftLocal trans => Lift.LiftLocal (Handler dp trans) where
103+ liftLocal =
104+ Lift.defaultLiftLocal
105+ (coerce :: Pack dp trans m a)
106+ (coerce :: Unpack dp trans m a)
107+
108+instance Lift.LiftCatch trans => Lift.LiftCatch (Handler dp trans) where
109+ liftCatch =
110+ Lift.defaultLiftCatch
111+ (coerce :: Pack dp trans m a)
112+ (coerce :: Unpack dp trans m a)
113+
114+instance Lift.LiftListen trans => Lift.LiftListen (Handler dp trans) where
115+ liftListen =
116+ Lift.defaultLiftListen
117+ (coerce :: Pack dp trans m a)
118+ (coerce :: Unpack dp trans m a)
119+
120+instance Lift.LiftPass trans => Lift.LiftPass (Handler dp trans) where
121+ liftPass =
122+ Lift.defaultLiftPass
123+ (coerce :: Pack dp trans m a)
124+ (coerce :: Unpack dp trans m a)
125+
126+instance Lift.LiftCallCC trans => Lift.LiftCallCC (Handler dp trans) where
127+ liftCallCC =
128+ Lift.defaultLiftCallCC
129+ (coerce :: Pack dp trans m a)
130+ (coerce :: Unpack dp trans m a)
131+ liftCallCC' =
132+ Lift.defaultLiftCallCC'
133+ (coerce :: Pack dp trans m a)
134+ (coerce :: Unpack dp trans m a)
135+
136+
137+-- Instances for mtl classes
138+
139+instance {-# OVERLAPPABLE #-}
140+ ( Class.MonadCont m
141+ , Lift.LiftCallCC trans
142+ , Monad (trans m)
143+ ) => Class.MonadCont (Handler dp trans m)
144+ where
145+ callCC = Lift.liftCallCC' Class.callCC
146+
147+instance {-# OVERLAPPABLE #-}
148+ ( Class.MonadReader r m
149+ , Lift.LiftLocal trans
150+ , Monad (trans m)
151+ ) => Class.MonadReader r (Handler dp trans m)
152+ where
153+ ask = lift Class.ask
154+ local = Lift.liftLocal Class.ask Class.local
155+ reader = lift . Class.reader
156+
157+instance {-# OVERLAPPABLE #-}
158+ ( Class.MonadState s m
159+ , MonadTrans trans
160+ , Monad (trans m)
161+ ) => Class.MonadState s (Handler dp trans m)
162+ where
163+ get = lift Class.get
164+ put = lift . Class.put
165+ state = lift . Class.state
166+
167+instance {-# OVERLAPPABLE #-}
168+ ( Class.MonadWriter w m
169+ , Lift.LiftListen trans
170+ , Lift.LiftPass trans
171+ , Monad (trans m)
172+ ) => Class.MonadWriter w (Handler dp trans m)
173+ where
174+ writer = lift . Class.writer
175+ tell = lift . Class.tell
176+ listen = Lift.liftListen Class.listen
177+ pass = Lift.liftPass Class.pass
178+
179+instance {-# OVERLAPPABLE #-}
180+ ( Class.MonadError e m
181+ , Lift.LiftCatch trans
182+ , Monad (trans m)
183+ ) => Class.MonadError e (Handler dp trans m)
184+ where
185+ throwError = lift . Class.throwError
186+ catchError = Lift.liftCatch Class.catchError
shell.nixdeleted−22
@@ -1,22 +0,0 @@
1−{ pkgs ? import <nixpkgs> {},
2− hc ? "ghc844"
3−}:
4−
5−pkgs.stdenv.mkDerivation rec {
6− name = "ether";
7− buildInputs = [
8− pkgs.haskell.compiler.${hc}
9− pkgs.git
10− pkgs.zlib
11− pkgs.cabal-install
12− pkgs.pkgconfig
13− ];
14− shellHook = ''
15− export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH
16− export LANG=en_US.UTF-8
17− '';
18− LOCALE_ARCHIVE =
19− if pkgs.stdenv.isLinux
20− then "${pkgs.glibcLocales}/lib/locale/locale-archive"
21− else "";
22−}
src/Ether.hsdeleted−25
@@ -1,25 +0,0 @@
1−module Ether
2− ( module Control.Monad
3− , module Control.Monad.Fix
4− , module Control.Monad.Trans.Identity
5− , module Data.Functor.Identity
6− , module Data.Tagged
7− , module Ether.Reader
8− , module Ether.Writer
9− , module Ether.State
10− , module Ether.Except
11− , module Ether.TagDispatch
12− , module Ether.TaggedTrans
13− ) where
14−
15−import Control.Monad
16−import Control.Monad.Fix
17−import Control.Monad.Trans.Identity
18−import Data.Functor.Identity
19−import Data.Tagged
20−import Ether.Reader
21−import Ether.Writer
22−import Ether.State
23−import Ether.Except
24−import Ether.TagDispatch
25−import Ether.TaggedTrans
src/Ether/Except.hsdeleted−127
@@ -1,127 +0,0 @@
1−module Ether.Except
2− (
3− -- * MonadExcept class
4− MonadExcept
5− , throw
6− , catch
7− -- * The Except monad
8− , Except
9− , runExcept
10− -- * The ExceptT monad transformer
11− , ExceptT
12− , exceptT
13− , runExceptT
14− -- * MonadExcept class (implicit)
15− , MonadExcept'
16− , throw'
17− , catch'
18− -- * The Except monad (implicit)
19− , Except'
20− , runExcept'
21− -- * The ExceptT monad transformer (implicit)
22− , ExceptT'
23− , exceptT'
24− , runExceptT'
25− -- * Internal labels
26− , TAGGED
27− , EXCEPT
28− ) where
29−
30−import qualified Control.Monad.Except as T
31−import Control.Monad.Signatures (Catch)
32−import qualified Control.Monad.Trans.Lift.Catch as Lift
33−import Data.Coerce
34−import Data.Functor.Identity
35−
36−import Ether.TaggedTrans
37−import Ether.Internal
38−
39−class Monad m => MonadExcept tag e m | m tag -> e where
40−
41− -- | Is used within a monadic computation to begin exception processing.
42− throw :: e -> m a
43−
44− -- | A TaggedTrans function to handle previous exceptions and return to
45− -- normal execution.
46− catch :: m a -> (e -> m a) -> m a
47−
48−instance {-# OVERLAPPABLE #-}
49− ( Lift.LiftCatch t
50− , Monad (t m)
51− , MonadExcept tag e m
52− ) => MonadExcept tag e (t m) where
53− throw = Lift.lift . throw @tag
54− catch = Lift.liftCatch (catch @tag)
55−
56−-- | Encode type-level information for 'ExceptT'.
57−data EXCEPT
58−
59−-- | The parameterizable exception monad.
60−--
61−-- Computations are either exceptions or normal values.
62−--
63−-- The 'return' function returns a normal value, while '>>=' exits on
64−-- the first exception.
65−type Except tag e = ExceptT tag e Identity
66−
67−-- | The exception monad transformer.
68−--
69−-- The 'return' function returns a normal value, while '>>=' exits on
70−-- the first exception.
71−type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
72−
73−-- | Runs an 'Except' and returns either an exception or a normal value.
74−runExcept :: forall tag e a . Except tag e a -> Either e a
75−runExcept = coerce (T.runExcept @e @a)
76−
77−-- | Runs an 'ExceptT' and returns either an exception or a normal value.
78−runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
79−runExceptT = coerce (T.runExceptT @e @m @a)
80−
81−-- | Constructor for computations in the exception monad transformer.
82−exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
83−exceptT = coerce (T.ExceptT @e @m @a)
84−
85−type instance HandleSuper EXCEPT e trans = ()
86−type instance HandleConstraint EXCEPT e trans m =
87− T.MonadError e (trans m)
88−
89−instance Handle EXCEPT e (T.ExceptT e) where
90− handling r = r
91−
92−instance
93− ( Handle EXCEPT e trans
94− , Monad m, Monad (trans m)
95− ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
96− where
97−
98− throw =
99− handling @EXCEPT @e @trans @m $
100− coerce (T.throwError @e @(trans m) @a) ::
101− forall eff a . e -> TaggedTrans eff trans m a
102−
103− catch =
104− handling @EXCEPT @e @trans @m $
105− coerce (T.catchError @e @(trans m) @a) ::
106− forall eff a . Catch e (TaggedTrans eff trans m) a
107−
108−type MonadExcept' e = MonadExcept e e
109−
110−throw' :: forall e m a . MonadExcept' e m => e -> m a
111−throw' = throw @e
112−
113−catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
114−catch' = catch @e
115−
116−type Except' e = Except e e
117−
118−runExcept' :: Except' e a -> Either e a
119−runExcept' = runExcept
120−
121−type ExceptT' e = ExceptT e e
122−
123−exceptT' :: m (Either e a) -> ExceptT' e m a
124−exceptT' = exceptT
125−
126−runExceptT' :: ExceptT' e m a -> m (Either e a)
127−runExceptT' = runExceptT
src/Ether/Internal.hsdeleted−68
@@ -1,68 +0,0 @@
1−module Ether.Internal
2− ( Tagged(..)
3− , TagsK
4− , Tags
5− , HasLens(..)
6− , LensLike
7− , Lens
8− , Lens'
9− , ReifiedLens(..)
10− , ReifiedLens'
11− , view
12− , over
13− , HList(..)
14− , KindOf
15− , TAGGED
16− , HandleSuper
17− , HandleConstraint
18− , Handle(..)
19− , makeTupleInstancesHasLens
20− ) where
21−
22−import Control.Applicative
23−import Data.Coerce
24−import Data.Functor.Identity
25−import Data.Kind
26−import Data.Tagged
27−import GHC.Exts (Constraint)
28−
29−import Ether.Internal.HasLens
30−import Ether.Internal.Tags
31−import Ether.Internal.TH_TupleInstances (makeTupleInstancesHasLens)
32−import Ether.Internal.TupleInstances ()
33−
34−data TAGGED e t
35−
36−type K_Monad = Type -> Type
37−
38−type K_Trans = K_Monad -> K_Monad
39−
40−type family
41− HandleSuper
42− (eff :: keff)
43− (p :: kp)
44− (trans :: K_Trans)
45− :: Constraint
46−
47−type family
48− HandleConstraint
49− (eff :: keff)
50− (p :: kp)
51− (trans :: K_Trans) (m :: K_Monad)
52− :: Constraint
53−
54−class
55− HandleSuper eff p trans =>
56− Handle eff p (trans :: K_Trans) | eff trans -> p
57− where
58− handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
59−
60−newtype ReifiedLens s t a b = Lens (Lens s t a b)
61−
62−type ReifiedLens' s a = ReifiedLens s s a a
63−
64−view :: LensLike (Const a) s t a b -> s -> a
65−view l = coerce (l Const)
66−
67−over :: LensLike Identity s t a b -> (a -> b) -> s -> t
68−over = coerce
src/Ether/Internal/HasLens.hsdeleted−24
@@ -1,24 +0,0 @@
1−module Ether.Internal.HasLens
2− ( LensLike
3− , Lens
4− , Lens'
5− , HasLens(..)
6− ) where
7−
8−import Data.Tagged
9−import Data.Coerce
10−
11−type LensLike f s t a b = (a -> f b) -> s -> f t
12−
13−type Lens s t a b = forall f. Functor f => LensLike f s t a b
14−
15−type Lens' s a = Lens s s a a
16−
17−class HasLens tag outer inner | tag outer -> inner where
18− lensOf :: Lens' outer inner
19−
20−instance HasLens a a a where
21− lensOf = id
22−
23−instance HasLens t (Tagged t a) a where
24− lensOf = \f -> fmap coerce . f . coerce
src/Ether/Internal/TH_TupleInstances.hsdeleted−79
@@ -1,79 +0,0 @@
1−module Ether.Internal.TH_TupleInstances
2− ( makeTupleInstancesTagsK
3− , makeTupleInstancesTags
4− , makeTupleInstancesHasLens
5− ) where
6−
7−import Data.Tagged
8−import Data.Traversable
9−import Data.List as List
10−import qualified Language.Haskell.TH as TH
11−
12−import Ether.Internal.HasLens
13−import Ether.Internal.Tags
14−import Ether.Internal.TH_Utils
15−
16−makeTupleInstancesTagsK :: TH.DecsQ
17−makeTupleInstancesTagsK = do
18− for [2..tupCount] $ \n -> do
19− let
20− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
21− (\k -> TH.ConT ''Tagged `TH.AppT`
22− TH.VarT (tagName k) `TH.AppT`
23− TH.VarT (varName k)) <$> [0..n-1]
24− tagsList = List.foldr
25− (\a b -> TH.PromotedConsT `TH.AppT` a `TH.AppT` b)
26− TH.PromotedNilT
27− (TH.AppT (TH.ConT ''KindOf) . TH.VarT . tagName <$> [0..n-1])
28− return $
29− TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy] tagsList)
30−
31−makeTupleInstancesTags :: TH.DecsQ
32−makeTupleInstancesTags = do
33− for [2..tupCount] $ \n -> do
34− let
35− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
36− (\k -> TH.ConT ''Tagged `TH.AppT`
37− TH.VarT (tagName k) `TH.AppT`
38− TH.VarT (varName k)) <$> [0..n-1]
39− tagsList = List.foldr
40− (\a b -> TH.PromotedT 'HCons `TH.AppT` a `TH.AppT` b)
41− (TH.PromotedT 'HNil)
42− (TH.VarT . tagName <$> [0..n-1])
43− return $
44− TH.TySynInstD ''Tags (TH.TySynEqn [tupTy] tagsList)
45−
46−makeTupleInstancesHasLens :: [Int] -> TH.DecsQ
47−makeTupleInstancesHasLens range = List.concat <$> do
48− for range $ \n ->
49− for [0..n-1] $ \k -> do
50− let
51− tag = TH.mkName "tag"
52− prev = varName <$> [0..k-1]
53− cur = varName k
54− next = varName <$> [k+1..n-1]
55− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
56− ( map TH.VarT prev ++
57− [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
58− map TH.VarT next )
59− let
60− cur' = TH.mkName "x"
61− f = TH.mkName "f"
62− return $
63− TH.InstanceD Nothing []
64− (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
65− [ TH.FunD 'lensOf
66− [ TH.Clause
67− [TH.VarP f, TH.TupP
68− ( map TH.VarP prev ++
69− [TH.ConP 'Tagged [TH.VarP cur]] ++
70− map TH.VarP next )]
71− (TH.NormalB $
72− TH.VarE 'fmap `TH.AppE`
73− (TH.LamE [TH.VarP cur']
74− (TH.TupE
75− ( map TH.VarE prev ++
76− [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
77− map TH.VarE next ))) `TH.AppE`
78− (TH.VarE f `TH.AppE` TH.VarE cur) )
79− [] ] ]
src/Ether/Internal/TH_Utils.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Ether.Internal.TH_Utils
2− ( tupCount
3− , varName
4− , tagName
5− ) where
6−
7−import qualified Language.Haskell.TH as TH
8−
9−tupCount :: Int
10−tupCount = 62
11−
12−varName, tagName :: Int -> TH.Name
13−varName k = TH.mkName ('a' : show k)
14−tagName k = TH.mkName ('t' : show k)
src/Ether/Internal/Tags.hsdeleted−18
@@ -1,18 +0,0 @@
1−module Ether.Internal.Tags
2− ( Tags
3− , TagsK
4− , HList(..)
5− , KindOf
6− ) where
7−
8−import Data.Kind
9−
10−data HList xs where
11− HNil :: HList '[]
12− HCons :: x -> HList xs -> HList (x ': xs)
13−
14−type KindOf (a :: k) = k
15−
16−type family TagsK (p :: Type) :: [Type]
17−type family Tags (p :: Type) :: HList (TagsK p)
18−
src/Ether/Internal/TupleInstances.hsdeleted−24
@@ -1,24 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module Ether.Internal.TupleInstances () where
5−
6−import Data.Tagged
7−import Ether.Internal.Tags
8−import Ether.Internal.TH_TupleInstances
9−
10−type instance TagsK () = '[]
11−type instance TagsK (Tagged t a) = '[KindOf t]
12−type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
13−
14−makeTupleInstancesTagsK
15−
16−type instance Tags () = 'HNil
17−type instance Tags (Tagged t a) = 'HCons t 'HNil
18−type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
19−
20−makeTupleInstancesTags
21−
22−#ifndef DISABLE_TUP_INSTANCES
23−makeTupleInstancesHasLens [2..62]
24−#endif
src/Ether/Reader.hsdeleted−236
@@ -1,236 +0,0 @@
1−module Ether.Reader
2− (
3− -- * MonadReader class
4− MonadReader
5− , ask
6− , local
7− , reader
8− , asks
9− -- * The Reader monad
10− , Reader
11− , runReader
12− -- * The ReaderT monad transformer
13− , ReaderT
14− , readerT
15− , runReaderT
16− -- * The Reader monad (flattened)
17− , Readers
18− , runReaders
19− -- * The ReaderT monad transformer (flattened)
20− , ReadersT
21− , runReadersT
22− -- * MonadReader class (implicit)
23− , MonadReader'
24− , local'
25− , ask'
26− , reader'
27− , asks'
28− -- * The Reader monad (implicit)
29− , Reader'
30− , runReader'
31− -- * The ReaderT monad transformer (implicit)
32− , ReaderT'
33− , readerT'
34− , runReaderT'
35− -- * Internal labels
36− , TAGGED
37− , READER
38− , READERS
39− ) where
40−
41−import qualified Control.Monad.Reader as T
42−import qualified Control.Monad.Trans.Lift.Local as Lift
43−import Control.Monad.Trans.Lift.Local (Local)
44−import Data.Coerce
45−import Data.Functor.Identity
46−import Data.Kind
47−
48−import Ether.TaggedTrans
49−import Ether.Internal
50−
51−class Monad m => MonadReader tag r m | m tag -> r where
52−
53− {-# MINIMAL (ask | reader), local #-}
54−
55− -- | Retrieves the monad environment.
56− ask :: m r
57− ask = reader @tag id
58−
59− -- | Executes a computation in a modified environment.
60− local
61− :: (r -> r)
62− -- ^ The function to modify the environment.
63− -> m a
64− -- ^ @Reader@ to run in the modified environment.
65− -> m a
66−
67− -- | Retrieves a function of the current environment.
68− reader
69− :: (r -> a)
70− -- ^ The selector function to apply to the environment.
71− -> m a
72− reader f = fmap f (ask @tag)
73−
74−instance {-# OVERLAPPABLE #-}
75− ( Lift.LiftLocal t
76− , Monad (t m)
77− , MonadReader tag r m
78− ) => MonadReader tag r (t m)
79− where
80− ask = Lift.lift (ask @tag)
81− local = Lift.liftLocal (ask @tag) (local @tag)
82− reader = Lift.lift . reader @tag
83−
84−instance {-# OVERLAPPABLE #-}
85− ( Monad (trans m)
86− , MonadReader tag r (TaggedTrans effs trans m)
87− ) => MonadReader tag r (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
88− where
89−
90− ask =
91− (coerce ::
92− TaggedTrans effs trans m r ->
93− TaggedTrans (eff ': effs) trans m r)
94− (ask @tag)
95−
96− local =
97− (coerce :: forall a .
98− Lift.Local r (TaggedTrans effs trans m) a ->
99− Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
100− (local @tag)
101−
102− reader =
103− (coerce :: forall a .
104− ((r -> a) -> TaggedTrans effs trans m a) ->
105− ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
106− (reader @tag)
107−
108−-- | Retrieves a function of the current environment.
109−asks
110− :: forall tag r m a
111− . MonadReader tag r m
112− => (r -> a)
113− -- ^ The selector function to apply to the environment.
114− -> m a
115−asks = reader @tag
116−
117−-- | Encode type-level information for 'ReaderT'.
118−data READER
119−
120−-- | The parameterizable reader monad.
121−--
122−-- Computations are functions of a shared environment.
123−--
124−-- The 'return' function ignores the environment, while '>>=' passes
125−-- the inherited environment to both subcomputations.
126−type Reader tag r = ReaderT tag r Identity
127−
128−-- | The reader monad transformer,
129−-- which adds a read-only environment to the given monad.
130−--
131−-- The 'return' function ignores the environment, while '>>=' passes
132−-- the inherited environment to both subcomputations.
133−type ReaderT tag r = TaggedTrans (TAGGED READER tag) (T.ReaderT r)
134−
135−-- | Constructor for computations in the reader monad transformer.
136−readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
137−readerT = coerce (T.ReaderT @r @m @a)
138−
139−-- | Runs a 'ReaderT' with the given environment
140−-- and returns the final value.
141−runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
142−runReaderT = coerce (T.runReaderT @r @m @a)
143−
144−-- | Runs a 'ReaderT' with the given environment
145−-- and returns the final value.
146−runReader :: forall tag r a . Reader tag r a -> r -> a
147−runReader = coerce (T.runReader @r @a)
148−
149−type instance HandleSuper READER r trans = ()
150−type instance HandleConstraint READER r trans m =
151− T.MonadReader r (trans m)
152−
153−instance Handle READER r (T.ReaderT r) where
154− handling r = r
155−
156−instance
157− ( Handle READER r trans
158− , Monad m, Monad (trans m)
159− ) => MonadReader tag r (TaggedTrans (TAGGED READER tag) trans m)
160− where
161−
162− ask =
163− handling @READER @r @trans @m $
164− coerce (T.ask @r @(trans m))
165−
166− local =
167− handling @READER @r @trans @m $
168− coerce (T.local @r @(trans m) @a) ::
169− forall eff a . Local r (TaggedTrans eff trans m) a
170−
171− reader =
172− handling @READER @r @trans @m $
173− coerce (T.reader @r @(trans m) @a) ::
174− forall eff a . (r -> a) -> TaggedTrans eff trans m a
175−
176−instance
177− ( HasLens tag payload r
178− , Handle READER payload trans
179− , Monad m, Monad (trans m)
180− ) => MonadReader tag r (TaggedTrans (TAGGED READER tag ': effs) trans m)
181− where
182−
183− ask =
184− handling @READER @payload @trans @m $
185− (coerce :: forall eff a .
186− trans m a ->
187− TaggedTrans eff trans m a)
188− (T.asks (view (lensOf @tag @payload @r)))
189−
190− local f =
191− handling @READER @payload @trans @m $
192− (coerce :: forall eff a .
193− (trans m a -> trans m a) ->
194− (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
195− (T.local (over (lensOf @tag @payload @r) f))
196−
197−type family READERS (ts :: HList xs) :: [Type] where
198− READERS 'HNil = '[]
199− READERS ('HCons t ts) = TAGGED READER t ': READERS ts
200−
201−type ReadersT r = TaggedTrans (READERS (Tags r)) (T.ReaderT r)
202−
203−type Readers r = ReadersT r Identity
204−
205−runReadersT :: forall p m a . ReadersT p m a -> p -> m a
206−runReadersT = coerce (T.runReaderT @p @m @a)
207−
208−runReaders :: forall p a . Readers p a -> p -> a
209−runReaders = coerce (T.runReader @p @a)
210−
211−type ReaderT' r = ReaderT r r
212−
213−readerT' :: (r -> m a) -> ReaderT' r m a
214−readerT' = readerT
215−
216−runReaderT' :: ReaderT' r m a -> r -> m a
217−runReaderT' = runReaderT
218−
219−type Reader' r = Reader r r
220−
221−runReader' :: Reader' r a -> r -> a
222−runReader' = runReader
223−
224−type MonadReader' r = MonadReader r r
225−
226−local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
227−local' = local @r
228−
229−ask' :: forall r m . MonadReader' r m => m r
230−ask' = ask @r
231−
232−reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
233−reader' = reader @r
234−
235−asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
236−asks' = asks @r
src/Ether/State.hsdeleted−415
@@ -1,415 +0,0 @@
1−module Ether.State
2− (
3− -- * MonadState class
4− MonadState
5− , get
6− , put
7− , state
8− , modify
9− , gets
10− -- * The State monad
11− , State
12− , runState
13− , evalState
14− , execState
15− -- * The StateT monad transformer
16− , StateT
17− , stateT
18− , runStateT
19− , evalStateT
20− , execStateT
21− -- * The State monad (lazy)
22− , LazyState
23− , runLazyState
24− , evalLazyState
25− , execLazyState
26− -- * The StateT monad transformer (lazy)
27− , LazyStateT
28− , lazyStateT
29− , runLazyStateT
30− , evalLazyStateT
31− , execLazyStateT
32− -- * The State monad (flattened)
33− , States
34− , runStates
35− -- * The StateT monad transformer (flattened)
36− , StatesT
37− , runStatesT
38− -- * MonadState class (implicit)
39− , MonadState'
40− , get'
41− , put'
42− , state'
43− , modify'
44− , gets'
45− -- * The State monad (implicit)
46− , State'
47− , runState'
48− , evalState'
49− , execState'
50− -- * The StateT monad transformer (implicit)
51− , StateT'
52− , stateT'
53− , runStateT'
54− , evalStateT'
55− , execStateT'
56− -- * The State monad (lazy, implicit)
57− , LazyState'
58− , runLazyState'
59− , evalLazyState'
60− , execLazyState'
61− -- * The StateT monad transformer (lazy, implicit)
62− , LazyStateT'
63− , lazyStateT'
64− , runLazyStateT'
65− , evalLazyStateT'
66− , execLazyStateT'
67− -- * Zoom
68− , ZoomT
69− , zoom
70− -- * Internal labels
71− , TAGGED
72− , STATE
73− , STATES
74− , ZOOM
75− ) where
76−
77−import qualified Control.Monad.State.Class as T
78−import qualified Control.Monad.Trans as Lift
79−import Control.Monad.Trans.Identity
80−import qualified Control.Monad.Trans.State.Lazy as T.Lazy
81−import qualified Control.Monad.Trans.State.Strict as T.Strict
82−import Data.Coerce
83−import Data.Functor.Identity
84−import Data.Kind
85−import Data.Proxy
86−import Data.Reflection
87−
88−import Ether.Internal
89−import Ether.TaggedTrans
90−
91−class Monad m => MonadState tag s m | m tag -> s where
92−
93− {-# MINIMAL state | get, put #-}
94−
95− -- | Return the state from the internals of the monad.
96− get :: m s
97− get = state @tag (\s -> (s, s))
98−
99− -- | Replace the state inside the monad.
100− put :: s -> m ()
101− put s = state @tag (\_ -> ((), s))
102−
103− -- | Embed a simple state action into the monad.
104− state :: (s -> (a, s)) -> m a
105− state f = do
106− s <- get @tag
107− let ~(a, s') = f s
108− put @tag s'
109− return a
110−
111−instance {-# OVERLAPPABLE #-}
112− ( Lift.MonadTrans t
113− , Monad (t m)
114− , MonadState tag s m
115− ) => MonadState tag s (t m)
116− where
117− get = Lift.lift (get @tag)
118− put = Lift.lift . put @tag
119− state = Lift.lift . state @tag
120−
121−instance {-# OVERLAPPABLE #-}
122− ( Monad (trans m)
123− , MonadState tag s (TaggedTrans effs trans m)
124− ) => MonadState tag s (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
125− where
126−
127− get =
128− (coerce ::
129− TaggedTrans effs trans m s ->
130− TaggedTrans (eff ': effs) trans m s)
131− (get @tag)
132−
133− put =
134− (coerce ::
135− (s -> TaggedTrans effs trans m ()) ->
136− (s -> TaggedTrans (eff ': effs) trans m ()))
137− (put @tag)
138−
139− state =
140− (coerce :: forall a .
141− ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
142− ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
143− (state @tag)
144−
145−-- | Modifies the state inside a state monad.
146−modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
147−modify f = state @tag (\s -> ((), f s))
148−
149−-- | Gets specific component of the state, using a projection function supplied.
150−gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
151−gets f = fmap f (get @tag)
152−
153−-- | Encode type-level information for 'StateT'.
154−data STATE
155−
156−type instance HandleSuper STATE s trans = ()
157−type instance HandleConstraint STATE s trans m =
158− T.MonadState s (trans m)
159−
160−instance Handle STATE s (T.Strict.StateT s) where
161− handling r = r
162−
163−instance Handle STATE s (T.Lazy.StateT s) where
164− handling r = r
165−
166−instance
167− ( Handle STATE s trans
168− , Monad m, Monad (trans m)
169− ) => MonadState tag s (TaggedTrans (TAGGED STATE tag) trans m)
170− where
171−
172− get =
173− handling @STATE @s @trans @m $
174− coerce (T.get @s @(trans m))
175−
176− put =
177− handling @STATE @s @trans @m $
178− coerce (T.put @s @(trans m))
179−
180− state =
181− handling @STATE @s @trans @m $
182− coerce (T.state @s @(trans m) @a) ::
183− forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
184−
185−instance
186− ( HasLens tag payload s
187− , Handle STATE payload trans
188− , Monad m, Monad (trans m)
189− ) => MonadState tag s (TaggedTrans (TAGGED STATE tag ': effs) trans m)
190− where
191−
192− get =
193− handling @STATE @payload @trans @m $
194− (coerce :: forall eff a .
195− trans m a ->
196− TaggedTrans eff trans m a)
197− (T.gets (view (lensOf @tag @payload @s)))
198−
199− put s =
200− handling @STATE @payload @trans @m $
201− (coerce :: forall eff a .
202− trans m a ->
203− TaggedTrans eff trans m a)
204− (T.modify (over (lensOf @tag @payload @s) (const s)))
205−
206− state f =
207− handling @STATE @payload @trans @m $
208− (coerce :: forall eff a .
209− trans m a ->
210− TaggedTrans eff trans m a)
211− (T.state (lensOf @tag @payload @s f))
212−
213−-- | The parametrizable state monad.
214−--
215−-- Computations have access to a mutable state.
216−--
217−-- The 'return' function leaves the state unchanged, while '>>=' uses
218−-- the final state of the first computation as the initial state of the second.
219−type State tag r = StateT tag r Identity
220−
221−-- | The state monad transformer.
222−--
223−-- The 'return' function leaves the state unchanged, while '>>=' uses
224−-- the final state of the first computation as the initial state of the second.
225−type StateT tag s = TaggedTrans (TAGGED STATE tag) (T.Strict.StateT s)
226−
227−-- | Constructor for computations in the state monad transformer.
228−stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
229−stateT = coerce (T.Strict.StateT @s @m @a)
230−
231−-- | Runs a 'StateT' with the given initial state
232−-- and returns both the final value and the final state.
233−runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
234−runStateT = coerce (T.Strict.runStateT @s @m @a)
235−
236−-- | Runs a 'StateT' with the given initial state
237−-- and returns the final value, discarding the final state.
238−evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
239−evalStateT = coerce (T.Strict.evalStateT @m @s @a)
240−
241−-- | Runs a 'StateT' with the given initial state
242−-- and returns the final state, discarding the final value.
243−execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
244−execStateT = coerce (T.Strict.execStateT @m @s @a)
245−
246−-- | Runs a 'State' with the given initial state
247−-- and returns both the final value and the final state.
248−runState :: forall tag s a . State tag s a -> s -> (a, s)
249−runState = coerce (T.Strict.runState @s @a)
250−
251−-- | Runs a 'State' with the given initial state
252−-- and returns the final value, discarding the final state.
253−evalState :: forall tag s a . State tag s a -> s -> a
254−evalState = coerce (T.Strict.evalState @s @a)
255−
256−-- | Runs a 'State' with the given initial state
257−-- and returns the final state, discarding the final value.
258−execState :: forall tag s a . State tag s a -> s -> s
259−execState = coerce (T.Strict.execState @s @a)
260−
261−-- | The parametrizable state monad.
262−--
263−-- Computations have access to a mutable state.
264−--
265−-- The 'return' function leaves the state unchanged, while '>>=' uses
266−-- the final state of the first computation as the initial state of the second.
267−type LazyState tag r = LazyStateT tag r Identity
268−
269−-- | The state monad transformer.
270−--
271−-- The 'return' function leaves the state unchanged, while '>>=' uses
272−-- the final state of the first computation as the initial state of the second.
273−type LazyStateT tag s = TaggedTrans (TAGGED STATE tag) (T.Lazy.StateT s)
274−
275−-- | Constructor for computations in the state monad transformer.
276−lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
277−lazyStateT = coerce (T.Lazy.StateT @s @m @a)
278−
279−-- | Runs a 'StateT' with the given initial state
280−-- and returns both the final value and the final state.
281−runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
282−runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
283−
284−-- | Runs a 'StateT' with the given initial state
285−-- and returns the final value, discarding the final state.
286−evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
287−evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
288−
289−-- | Runs a 'StateT' with the given initial state
290−-- and returns the final state, discarding the final value.
291−execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
292−execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
293−
294−-- | Runs a 'State' with the given initial state
295−-- and returns both the final value and the final state.
296−runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
297−runLazyState = coerce (T.Lazy.runState @s @a)
298−
299−-- | Runs a 'State' with the given initial state
300−-- and returns the final value, discarding the final state.
301−evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
302−evalLazyState = coerce (T.Lazy.evalState @s @a)
303−
304−-- | Runs a 'State' with the given initial state
305−-- and returns the final state, discarding the final value.
306−execLazyState :: forall tag s a . LazyState tag s a -> s -> s
307−execLazyState = coerce (T.Lazy.execState @s @a)
308−
309−type family STATES (ts :: HList xs) :: [Type] where
310− STATES 'HNil = '[]
311− STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
312−
313−type StatesT s = TaggedTrans (STATES (Tags s)) (T.Strict.StateT s)
314−
315−type States s = StatesT s Identity
316−
317−runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
318−runStatesT = coerce (T.Strict.runStateT @p @m @a)
319−
320−runStates :: forall p a . States p a -> p -> (a, p)
321−runStates = coerce (T.Strict.runState @p @a)
322−
323−type StateT' s = StateT s s
324−
325−stateT' :: (s -> m (a, s)) -> StateT' s m a
326−stateT' = stateT
327−
328−runStateT' :: StateT' s m a -> s -> m (a, s)
329−runStateT' = runStateT
330−
331−runState' :: State' s a -> s -> (a, s)
332−runState' = runState
333−
334−evalStateT' :: Monad m => StateT' s m a -> s -> m a
335−evalStateT' = evalStateT
336−
337−type State' s = State s s
338−
339−evalState' :: State' s a -> s -> a
340−evalState' = evalState
341−
342−execStateT' :: Monad m => StateT' s m a -> s -> m s
343−execStateT' = execStateT
344−
345−execState' :: State' s a -> s -> s
346−execState' = execState
347−
348−type LazyStateT' s = LazyStateT s s
349−
350−lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
351−lazyStateT' = lazyStateT
352−
353−runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
354−runLazyStateT' = runLazyStateT
355−
356−runLazyState' :: LazyState' s a -> s -> (a, s)
357−runLazyState' = runLazyState
358−
359−evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
360−evalLazyStateT' = evalLazyStateT
361−
362−type LazyState' s = LazyState s s
363−
364−evalLazyState' :: LazyState' s a -> s -> a
365−evalLazyState' = evalLazyState
366−
367−execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
368−execLazyStateT' = execLazyStateT
369−
370−execLazyState' :: LazyState' s a -> s -> s
371−execLazyState' = execLazyState
372−
373−type MonadState' s = MonadState s s
374−
375−get' :: forall s m . MonadState' s m => m s
376−get' = get @s
377−
378−gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
379−gets' = gets @s
380−
381−put' :: forall s m . MonadState' s m => s -> m ()
382−put' = put @s
383−
384−state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
385−state' = state @s
386−
387−modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
388−modify' = modify @s
389−
390−-- | Encode type-level information for 'zoom'.
391−data ZOOM t z
392−
393−type ZoomT t (z :: Type) = TaggedTrans (ZOOM t z) IdentityT
394−
395−-- | Zoom into a part of a state using a lens.
396−zoom
397− :: forall tag sOuter sInner m a
398− . Lens' sOuter sInner
399− -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
400− -> m a
401−zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
402−
403−instance
404− ( MonadState tag sOuter m
405− , Reifies z (ReifiedLens' sOuter sInner)
406− , trans ~ IdentityT
407− ) => MonadState tag sInner (TaggedTrans (ZOOM tag z) trans m)
408− where
409− state =
410− (coerce :: forall eff r a .
411− (r -> m a) ->
412− (r -> TaggedTrans eff trans m a))
413− (state @tag . l)
414− where
415− Lens l = reflect (Proxy :: Proxy z)
src/Ether/TagDispatch.hsdeleted−138
@@ -1,138 +0,0 @@
1−{- |
2−
3−Type-level machinery to manipulate constraints on the monad
4−transformer stack.
5−
6−Out of the box it provides the following dispatch strategies:
7−
8−* 'tagAttach' to use functions defined using untagged monad classes
9− as if they were defined using tagged ones.
10−
11−* 'tagReplace' to use functions defined using one tag
12− as if they were defined using another one.
13−
14−> import Ether
15−> import Control.Monad.State as Mtl
16−>
17−> data Foo
18−> data Bar
19−>
20−> f :: Mtl.MonadState Int m => m String
21−> f = fmap show Mtl.get
22−>
23−> g :: Ether.MonadState Foo Int m => m String
24−> g = tagAttach @Foo f
25−>
26−> h :: Ether.MonadState Bar Int m => m String
27−> h = tagReplace @Foo @Bar g
28−
29−-}
30−
31−module Ether.TagDispatch
32− (
33− -- * The Tag Attach monad transformer
34− TagAttachT
35− , tagAttach
36− -- * The Tag Replace monad transformer
37− , TagReplaceT
38− , tagReplace
39− -- * Internal labels
40− , TAG_ATTACH
41− , TAG_REPLACE
42− ) where
43−
44−import qualified Control.Monad.Error.Class as Mtl
45−import qualified Control.Monad.Reader.Class as Mtl
46−import qualified Control.Monad.State.Class as Mtl
47−import qualified Control.Monad.Writer.Class as Mtl
48−
49−import Ether.Except
50−import Ether.Reader
51−import Ether.State
52−import Ether.Writer
53−import Ether.TaggedTrans
54−
55−import Control.Monad.Trans.Identity
56−import Data.Coerce
57−
58−-- | Encode type-level information for 'tagAttach'.
59−data TAG_ATTACH t
60−
61−type TagAttachT t = TaggedTrans (TAG_ATTACH t) IdentityT
62−
63−-- | Attach a tag to untagged transformers.
64−tagAttach :: forall tag m a . TagAttachT tag m a -> m a
65−tagAttach = coerce (runIdentityT @_ @m @a)
66−
67−instance {-# OVERLAPPING #-}
68− ( MonadReader tag r m, trans ~ IdentityT
69− ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
70− where
71− ask = ask @tag
72− local = local @tag
73− reader = reader @tag
74−
75−instance {-# OVERLAPPING #-}
76− ( MonadState tag s m, trans ~ IdentityT
77− ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
78− where
79− get = get @tag
80− put = put @tag
81− state = state @tag
82−
83−instance {-# OVERLAPPING #-}
84− ( MonadExcept tag e m, trans ~ IdentityT
85− ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
86− where
87− throwError = throw @tag
88− catchError = catch @tag
89−
90−instance {-# OVERLAPPING #-}
91− ( MonadWriter tag w m, trans ~ IdentityT
92− ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
93− where
94− writer = writer @tag
95− tell = tell @tag
96− listen = listen @tag
97− pass = pass @tag
98−
99−-- | Encode type-level information for 'tagReplace'.
100−data TAG_REPLACE tOld tNew
101−
102−type TagReplaceT tOld tNew = TaggedTrans (TAG_REPLACE tOld tNew) IdentityT
103−
104−-- | Replace a tag with another tag.
105−tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
106−tagReplace = coerce (runIdentityT @_ @m @a)
107−
108−instance
109− ( MonadReader tNew r m, trans ~ IdentityT
110− ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
111− where
112− ask = ask @tNew
113− local = local @tNew
114− reader = reader @tNew
115−
116−instance
117− ( MonadState tNew s m, trans ~ IdentityT
118− ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
119− where
120− get = get @tNew
121− put = put @tNew
122− state = state @tNew
123−
124−instance
125− ( MonadExcept tNew e m, trans ~ IdentityT
126− ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
127− where
128− throw = throw @tNew
129− catch = catch @tNew
130−
131−instance
132− ( MonadWriter tNew w m, trans ~ IdentityT
133− ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
134− where
135− writer = writer @tNew
136− tell = tell @tNew
137− listen = listen @tNew
138− pass = pass @tNew
src/Ether/TaggedTrans.hsdeleted−206
@@ -1,206 +0,0 @@
1−-- The use of ImpredicativeTypes here is safe, see discussion under GitHub issue
2−-- #35. It's only needed to allow the visible type application of a polytype.
3−{-# LANGUAGE ImpredicativeTypes #-}
4−
5−module Ether.TaggedTrans
6− ( TaggedTrans(..)
7− ) where
8−
9−import Control.Applicative
10−import Control.Monad (MonadPlus)
11−import Control.Monad.Fix (MonadFix)
12−import Control.Monad.Trans.Class (MonadTrans, lift)
13−import Control.Monad.IO.Class (MonadIO)
14−import Control.Monad.Morph (MFunctor(..), MMonad(..))
15−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
16−
17−import qualified Control.Monad.Base as MB
18−import qualified Control.Monad.Trans.Control as MC
19−
20−import qualified Control.Monad.Trans.Lift.StT as Lift
21−import qualified Control.Monad.Trans.Lift.Local as Lift
22−import qualified Control.Monad.Trans.Lift.Catch as Lift
23−import qualified Control.Monad.Trans.Lift.Listen as Lift
24−import qualified Control.Monad.Trans.Lift.Pass as Lift
25−import qualified Control.Monad.Trans.Lift.CallCC as Lift
26−
27−import qualified Control.Monad.Cont.Class as Mtl
28−import qualified Control.Monad.Reader.Class as Mtl
29−import qualified Control.Monad.State.Class as Mtl
30−import qualified Control.Monad.Writer.Class as Mtl
31−import qualified Control.Monad.Error.Class as Mtl
32−
33−import GHC.Generics (Generic)
34−import Data.Coerce (coerce)
35−
36−newtype TaggedTrans tag trans m a = TaggedTrans (trans m a)
37− deriving
38− ( Generic
39− , Functor, Applicative, Alternative, Monad, MonadPlus
40− , MonadFix, MonadTrans, MonadIO
41− , MonadThrow, MonadCatch, MonadMask )
42−
43−type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
44−
45−type Unpack tag trans m a = TaggedTrans tag trans m a -> trans m a
46−
47−instance
48− ( MB.MonadBase b (trans m)
49− ) => MB.MonadBase b (TaggedTrans tag trans m)
50− where
51− liftBase =
52− (coerce :: forall a .
53− (b a -> trans m a) ->
54− (b a -> TaggedTrans tag trans m a))
55− MB.liftBase
56−
57−instance
58− ( MC.MonadTransControl trans
59− ) => MC.MonadTransControl (TaggedTrans tag trans)
60− where
61− type StT (TaggedTrans tag trans) a = MC.StT trans a
62−
63− liftWith = MC.defaultLiftWith
64− (coerce :: Pack tag trans m a)
65− (coerce :: Unpack tag trans m a)
66−
67− restoreT = MC.defaultRestoreT
68− (coerce :: Pack tag trans m a)
69−
70−type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
71−
72−newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
73−
74−coerceLiftBaseWith ::
75− LiftBaseWith b (trans m) a ->
76− LiftBaseWith b (TaggedTrans tag trans m) a
77−coerceLiftBaseWith lbw =
78− unLBW (coerce (LBW lbw))
79−
80−instance
81− ( MC.MonadBaseControl b (trans m)
82− ) => MC.MonadBaseControl b (TaggedTrans tag trans m)
83− where
84− type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
85−
86− liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
87−
88− restoreM =
89− (coerce :: forall a .
90− (MC.StM (trans m) a -> trans m a) ->
91− (MC.StM (trans m) a -> TaggedTrans tag trans m a))
92− MC.restoreM
93−
94−type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
95−
96−instance Lift.LiftLocal trans => Lift.LiftLocal (TaggedTrans tag trans) where
97− liftLocal =
98− Lift.defaultLiftLocal
99− (coerce :: Pack tag trans m a)
100− (coerce :: Unpack tag trans m a)
101−
102−instance Lift.LiftCatch trans => Lift.LiftCatch (TaggedTrans tag trans) where
103− liftCatch =
104− Lift.defaultLiftCatch
105− (coerce :: Pack tag trans m a)
106− (coerce :: Unpack tag trans m a)
107−
108−instance Lift.LiftListen trans => Lift.LiftListen (TaggedTrans tag trans) where
109− liftListen =
110− Lift.defaultLiftListen
111− (coerce :: Pack tag trans m a)
112− (coerce :: Unpack tag trans m a)
113−
114−instance Lift.LiftPass trans => Lift.LiftPass (TaggedTrans tag trans) where
115− liftPass =
116− Lift.defaultLiftPass
117− (coerce :: Pack tag trans m a)
118− (coerce :: Unpack tag trans m a)
119−
120−instance Lift.LiftCallCC trans => Lift.LiftCallCC (TaggedTrans tag trans) where
121− liftCallCC =
122− Lift.defaultLiftCallCC
123− (coerce :: Pack tag trans m a)
124− (coerce :: Unpack tag trans m a)
125− liftCallCC' =
126− Lift.defaultLiftCallCC'
127− (coerce :: Pack tag trans m a)
128− (coerce :: Unpack tag trans m a)
129−
130−
131−-- Instances for mtl classes
132−
133−instance
134− ( Mtl.MonadCont m
135− , Lift.LiftCallCC trans
136− , Monad (trans m)
137− ) => Mtl.MonadCont (TaggedTrans tag trans m)
138− where
139− callCC = Lift.liftCallCC' Mtl.callCC
140−
141−instance
142− ( Mtl.MonadReader r m
143− , Lift.LiftLocal trans
144− , Monad (trans m)
145− ) => Mtl.MonadReader r (TaggedTrans tag trans m)
146− where
147− ask = lift Mtl.ask
148− local = Lift.liftLocal Mtl.ask Mtl.local
149− reader = lift . Mtl.reader
150−
151−instance
152− ( Mtl.MonadState s m
153− , MonadTrans trans
154− , Monad (trans m)
155− ) => Mtl.MonadState s (TaggedTrans tag trans m)
156− where
157− get = lift Mtl.get
158− put = lift . Mtl.put
159− state = lift . Mtl.state
160−
161−instance
162− ( Mtl.MonadWriter w m
163− , Lift.LiftListen trans
164− , Lift.LiftPass trans
165− , Monad (trans m)
166− ) => Mtl.MonadWriter w (TaggedTrans tag trans m)
167− where
168− writer = lift . Mtl.writer
169− tell = lift . Mtl.tell
170− listen = Lift.liftListen Mtl.listen
171− pass = Lift.liftPass Mtl.pass
172−
173−instance
174− ( Mtl.MonadError e m
175− , Lift.LiftCatch trans
176− , Monad (trans m)
177− ) => Mtl.MonadError e (TaggedTrans tag trans m)
178− where
179− throwError = lift . Mtl.throwError
180− catchError = Lift.liftCatch Mtl.catchError
181−
182−type Hoist trans =
183− forall m n b . Monad m =>
184− (forall a . m a -> n a) -> trans m b -> trans n b
185−
186−-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
187−-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
188−instance MFunctor trans => MFunctor (TaggedTrans tag trans) where
189− hoist =
190− coerce
191− @(Hoist trans)
192− @(Hoist (TaggedTrans tag trans))
193− hoist
194−
195−type Embed trans =
196− forall n m b . Monad n =>
197− (forall a . m a -> trans n a) -> trans m b -> trans n b
198−
199−-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
200−-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
201−instance MMonad trans => MMonad (TaggedTrans tag trans) where
202− embed =
203− coerce
204− @(Embed trans)
205− @(Embed (TaggedTrans tag trans))
206− embed
src/Ether/Writer.hsdeleted−287
@@ -1,287 +0,0 @@
1−module Ether.Writer
2− (
3− -- * MonadWriter class
4− MonadWriter
5− , writer
6− , tell
7− , listen
8− , pass
9− , listens
10− , censor
11− -- * The Writer monad
12− , Writer
13− , runWriter
14− , execWriter
15− -- * The WriterT monad transformer
16− , WriterT
17− , writerT
18− , runWriterT
19− , execWriterT
20− -- * The Writer monad (lazy)
21− , LazyWriter
22− , runLazyWriter
23− , execLazyWriter
24− -- * The WriterT monad transformer (lazy)
25− , LazyWriterT
26− , lazyWriterT
27− , runLazyWriterT
28− , execLazyWriterT
29− -- * MonadWriter class (implicit)
30− , MonadWriter'
31− , writer'
32− , tell'
33− , listen'
34− , pass'
35− , listens'
36− , censor'
37− -- * The Writer monad (implicit)
38− , Writer'
39− , runWriter'
40− , execWriter'
41− -- * The WriterT monad transformer (implicit)
42− , WriterT'
43− , writerT'
44− , runWriterT'
45− , execWriterT'
46− -- * The Writer monad (lazy, implicit)
47− , LazyWriter'
48− , runLazyWriter'
49− , execLazyWriter'
50− -- * The WriterT monad transformer (lazy, implicit)
51− , LazyWriterT'
52− , lazyWriterT'
53− , runLazyWriterT'
54− , execLazyWriterT'
55− -- * Internal labels
56− , TAGGED
57− , WRITER
58− ) where
59−
60−import Control.Monad.Signatures (Listen, Pass)
61−import qualified Control.Monad.Trans.Lift.Listen as Lift
62−import qualified Control.Monad.Trans.Lift.Pass as Lift
63−import qualified Control.Monad.Writer.Class as T
64−import qualified Control.Monad.Writer.CPS as T.CPS
65−import qualified Control.Monad.Writer.Lazy as T.Lazy
66−import Data.Coerce
67−import Data.Functor.Identity
68−
69−import Ether.Internal
70−import Ether.TaggedTrans
71−
72−class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
73−
74− {-# MINIMAL (writer | tell), listen, pass #-}
75−
76− -- | Embed a simple writer action.
77− writer :: (a, w) -> m a
78− writer ~(a, w) = a <$ tell @tag w
79−
80− -- | Append a value to the accumulator within the monad.
81− tell :: w -> m ()
82− tell w = writer @tag ((),w)
83−
84− -- | Execute an action and add its accumulator
85− -- to the value of the computation.
86− listen :: m a -> m (a, w)
87−
88− -- | Execute an action which returns a value and a function,
89− -- and return the value, applying the function to the accumulator.
90− pass :: m (a, w -> w) -> m a
91−
92−instance {-# OVERLAPPABLE #-}
93− ( Lift.LiftListen t
94− , Lift.LiftPass t
95− , Monad (t m)
96− , MonadWriter tag w m
97− , Monoid w
98− ) => MonadWriter tag w (t m) where
99− writer = Lift.lift . writer @tag
100− tell = Lift.lift . tell @tag
101− listen = Lift.liftListen (listen @tag)
102− pass = Lift.liftPass (pass @tag)
103−
104−-- | Execute an action and add the result of applying the given function to
105−-- its accumulator to the value of the computation.
106−listens :: forall tag w m a b . MonadWriter tag w m => (w -> b) -> m a -> m (a, b)
107−listens f m = do
108− ~(a, w) <- listen @tag m
109− return (a, f w)
110−
111−-- | Execute an action and apply a function to its accumulator.
112−censor :: forall tag w m a . MonadWriter tag w m => (w -> w) -> m a -> m a
113−censor f m = pass @tag $ do
114− a <- m
115− return (a, f)
116−
117−-- | Encode type-level information for 'WriterT'.
118−data WRITER
119−
120−type instance HandleSuper WRITER w trans = Monoid w
121−type instance HandleConstraint WRITER w trans m =
122− T.MonadWriter w (trans m)
123−
124−instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
125− handling r = r
126−
127−instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
128− handling r = r
129−
130−instance
131− ( Handle WRITER w trans
132− , Monad m, Monad (trans m)
133− ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
134− where
135−
136− writer =
137− handling @WRITER @w @trans @m $
138− coerce (T.writer @w @(trans m) @a) ::
139− forall eff a . (a, w) -> TaggedTrans eff trans m a
140−
141− tell =
142− handling @WRITER @w @trans @m $
143− coerce (T.tell @w @(trans m))
144−
145− listen =
146− handling @WRITER @w @trans @m $
147− coerce (T.listen @w @(trans m) @a) ::
148− forall eff a . Listen w (TaggedTrans eff trans m) a
149−
150− pass =
151− handling @WRITER @w @trans @m $
152− coerce (T.pass @w @(trans m) @a) ::
153− forall eff a . Pass w (TaggedTrans eff trans m) a
154−
155−-- | The parametrizable writer monad.
156−--
157−-- Computations can accumulate a monoid value.
158−--
159−-- The 'return' function produces the output 'mempty', while '>>=' combines
160−-- the outputs of the subcomputations using 'mappend'.
161−type Writer tag w = WriterT tag w Identity
162−
163−-- | The writer monad transformer.
164−--
165−-- The 'return' function produces the output 'mempty', while '>>=' combines
166−-- the outputs of the subcomputations using 'mappend'.
167−type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
168−
169−-- | Constructor for computations in the writer monad transformer.
170−writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
171−writerT = coerce (T.CPS.writerT @m @w @a)
172−
173−-- | Runs a 'WriterT' and returns both the normal value
174−-- and the final accumulator.
175−runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
176−runWriterT = coerce (T.CPS.runWriterT @w @m @a)
177−
178−-- | Runs a 'Writer' and returns both the normal value
179−-- and the final accumulator.
180−runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
181−runWriter = coerce (T.CPS.runWriter @w @a)
182−
183−-- | Runs a 'WriterT' and returns the final accumulator,
184−-- discarding the normal value.
185−execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
186−execWriterT = coerce (T.CPS.execWriterT @m @w @a)
187−
188−-- | Runs a 'Writer' and returns the final accumulator,
189−-- discarding the normal value.
190−execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
191−execWriter = coerce (T.CPS.execWriter @w @a)
192−
193−-- | The parametrizable writer monad.
194−--
195−-- Computations can accumulate a monoid value.
196−--
197−-- The 'return' function produces the output 'mempty', while '>>=' combines
198−-- the outputs of the subcomputations using 'mappend'.
199−type LazyWriter tag w = LazyWriterT tag w Identity
200−
201−-- | The writer monad transformer.
202−--
203−-- The 'return' function produces the output 'mempty', while '>>=' combines
204−-- the outputs of the subcomputations using 'mappend'.
205−type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
206−
207−-- | Constructor for computations in the writer monad transformer.
208−lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
209−lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
210−
211−-- | Runs a 'WriterT' and returns both the normal value
212−-- and the final accumulator.
213−runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
214−runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
215−
216−-- | Runs a 'Writer' and returns both the normal value
217−-- and the final accumulator.
218−runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
219−runLazyWriter = coerce (T.Lazy.runWriter @w @a)
220−
221−-- | Runs a 'WriterT' and returns the final accumulator,
222−-- discarding the normal value.
223−execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
224−execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
225−
226−-- | Runs a 'Writer' and returns the final accumulator,
227−-- discarding the normal value.
228−execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
229−execLazyWriter = coerce (T.Lazy.execWriter @w @a)
230−
231−type Writer' w = Writer w w
232−
233−runWriter' :: Monoid w => Writer' w a -> (a, w)
234−runWriter' = runWriter
235−
236−execWriter' :: Monoid w => Writer' w a -> w
237−execWriter' = execWriter
238−
239−type WriterT' w = WriterT w w
240−
241−writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
242−writerT' = writerT
243−
244−runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
245−runWriterT' = runWriterT
246−
247−execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
248−execWriterT' = execWriterT
249−
250−type LazyWriter' w = LazyWriter w w
251−
252−runLazyWriter' :: LazyWriter' w a -> (a, w)
253−runLazyWriter' = runLazyWriter
254−
255−execLazyWriter' :: LazyWriter' w a -> w
256−execLazyWriter' = execLazyWriter
257−
258−type LazyWriterT' w = LazyWriterT w w
259−
260−lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
261−lazyWriterT' = lazyWriterT
262−
263−runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
264−runLazyWriterT' = runLazyWriterT
265−
266−execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
267−execLazyWriterT' = execLazyWriterT
268−
269−type MonadWriter' w = MonadWriter w w
270−
271−writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
272−writer' = writer @w
273−
274−tell' :: forall w m . MonadWriter' w m => w -> m ()
275−tell' = tell @w
276−
277−listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
278−listen' = listen @w
279−
280−pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
281−pass' = pass @w
282−
283−listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
284−listens' = listens @w
285−
286−censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
287−censor' = censor @w
stack.yamlnew file+7
@@ -0,0 +1,7 @@
1+resolver: lts-8.5
2+
3+packages:
4+- 'ether'
5+- 'ether-flatten'
6+- 'ether-zoom'
7+- 'ether-suite'
test/TupleInstances.hsdeleted−9
@@ -1,9 +0,0 @@
1−{-# OPTIONS -fno-warn-orphans #-}
2−{-# LANGUAGE CPP #-}
3−
4−module TupleInstances () where
5−
6−#ifdef DISABLE_TUP_INSTANCES
7−import Ether.Internal (makeTupleInstancesHasLens)
8−makeTupleInstancesHasLens [2]
9−#endif