on master help sign in
67 files changed+2467−2366
since splitsnapshots
unifiedsplit
.gitignore+18−1 .travis.yml+23−25 CHANGELOG.md+25 LICENSE+2−2 README.md−17 bench/Bench.hs+203 bench/TupleInstances.hs+9 ether.cabal+219−105 shell.nix+22 src/Control/Ether/Abbr.hs−60 src/Control/Ether/Implicit/Abbr.hs−25 src/Control/Ether/TH.hs−40 src/Control/Ether/Util.hs−22 src/Control/Monad/Ether.hs−14 src/Control/Monad/Ether/Except.hs−30 src/Control/Monad/Ether/Except/Class.hs−44 src/Control/Monad/Ether/Implicit.hs−14 src/Control/Monad/Ether/Implicit/Except.hs−62 src/Control/Monad/Ether/Implicit/Reader.hs−61 src/Control/Monad/Ether/Implicit/State.hs−8 src/Control/Monad/Ether/Implicit/State/Lazy.hs−86 src/Control/Monad/Ether/Implicit/State/Strict.hs−86 src/Control/Monad/Ether/Implicit/Writer.hs−81 src/Control/Monad/Ether/Reader.hs−19 src/Control/Monad/Ether/Reader/Class.hs−71 src/Control/Monad/Ether/State.hs−8 src/Control/Monad/Ether/State/Class.hs−73 src/Control/Monad/Ether/State/Lazy.hs−24 src/Control/Monad/Ether/State/Strict.hs−24 src/Control/Monad/Ether/Writer.hs−22 src/Control/Monad/Ether/Writer/Class.hs−82 src/Control/Monad/Trans/Ether/Dispatch.hs−184 src/Control/Monad/Trans/Ether/Except.hs−168 src/Control/Monad/Trans/Ether/Reader.hs−181 src/Control/Monad/Trans/Ether/State.hs−8 src/Control/Monad/Trans/Ether/State/Lazy.hs−196 src/Control/Monad/Trans/Ether/State/Strict.hs−196 src/Control/Monad/Trans/Ether/Writer.hs−192 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-ghc-7.8.4.yaml−35 stack.yaml−5 test/Regression.hs+8 test/Regression/T1.hs+25−14 test/Regression/T10.hs+43 test/Regression/T11.hs+50 test/Regression/T12.hs+30 test/Regression/T2.hs+9−11 test/Regression/T3.hs+15−16 test/Regression/T4.hs+6−8 test/Regression/T5.hs+8−11 test/Regression/T6.hs+14−16 test/Regression/T7.hs+7−6 test/Regression/T8.hs+12−13 test/Regression/T9.hs+49 test/TupleInstances.hs+9
.gitignore+18−1
@@ -1,4 +1,21 @@
1+# Cabal
12dist
2−.stack-work
3+dist-newstyle
34.cabal-sandbox/
45cabal.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+23−25
@@ -1,33 +1,31 @@
1−sudo: false
1+language: nix
2+
3+os:
4+ - linux
5+ - osx
26
37env:
4− - CABALVER=1.18 GHCVER=7.8.4
5− - CABALVER=1.22 GHCVER=7.10.3
8+ - HC=ghc822
9+ - HC=ghc844
10+ - HC=ghc861
611
712before_install:
8− - export PATH=/opt/ghc/$GHCVER/bin:/opt/cabal/$CABALVER/bin:$HOME/.cabal/bin:$PATH
9− - travis_retry cabal update
10−
11−install:
12− - cabal --version
13− - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
14− - cabal install --only-dependencies --enable-tests
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
1515
1616script:
17− - cabal configure --enable-tests --enable-library-coverage -v2
18− - cabal build
19− - cabal test
17+ - ./nix-cabal new-test ether:regression
18+ - ./nix-cabal new-bench ether:bench
2019
21−after_script:
22− - cabal install hpc-coveralls
23− - hpc-coveralls regression --exclude-dir=test
20+cache:
21+ directories:
22+ - ~/.cabal
23+ - ~/.ghc
2424
25−addons:
26− apt:
27− sources:
28− - hvr-ghc
29− packages:
30− - ghc-7.8.4
31− - ghc-7.10.3
32− - cabal-install-1.18
33− - cabal-install-1.22
25+matrix:
26+ # broken at the moment
27+ exclude:
28+ - os: osx
29+ env: HC=ghc822
30+ - os: osx
31+ env: HC=ghc861
CHANGELOG.md+25
@@ -1,11 +1,36 @@
1+0.5.1.0
2+-------
3+
4+* Disable `HasLens` for tuples via cabal flag.
5+
6+0.5.0.0
7+-------
8+
9+* Support only GHC 8.0 and higher.
10+* Use the `TypeApplications` extension to get rid of `Proxy`.
11+* 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+-------
21+
22+* Export DispatchT newtype constructor.
23+
1240.4.0.0
225-------
326
427* Poly-kinded tags.
528* Remove `Control.Ether.Tagged`.
629* Replace `Control.Ether.Wrapped` with `Control.Monad.Trans.Ether.Dispatch`.
30+* Unified tagged transformer type in `Control.Monad.Trans.Ether.Tagged`.
731* `MonadThrow`, `MonadCatch`, `MonadMask` instances.
832* Drop `newtype-generics`.
33+* Instance search is now more strict.
934
1035
11360.3.1.1
LICENSE+2−2
@@ -1,4 +1,4 @@
1−Copyright (c) 2015, Index Int
1+Copyright (c) 2017, Vladislav Zavialov
22
33All rights reserved.
44
@@ -13,7 +13,7 @@ modification, are permitted provided that the following conditions are met:
1313 disclaimer in the documentation and/or other materials provided
1414 with the distribution.
1515
16− * Neither the name of Index Int nor the names of other
16+ * Neither the name of Vladislav Zavialov nor the names of other
1717 contributors may be used to endorse or promote products derived
1818 from this software without specific prior written permission.
1919
README.md−17
@@ -2,25 +2,8 @@
22
33[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
44[![Hackage](https://img.shields.io/hackage/v/ether.svg)](https://hackage.haskell.org/package/ether)
5−[![Coveralls](https://img.shields.io/coveralls/int-index/ether.svg)](https://coveralls.io/github/int-index/ether)
6−[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/int-index/ether)
75
86
97Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
108and [transformers](https://hackage.haskell.org/package/transformers) with tagged
119monad transformers and classes in a compatible way.
12−
13−## Installation
14−
15−You can install `ether 0.3.1.1`
16−
17−1. using Cabal, from Hackage;
18−2. using Stack, from Stackage;
19−3. using Portage, from Gentoo Haskell Overlay.
20−
21−If unsure, use [Stack](https://github.com/commercialhaskell/stack).
22−
23−## Getting Started
24−
25−To get started, read the introduction on the [homepage](https://int-index.github.io/ether/).
26−If you need help with Ether or if you have any questions about it, ask me in the Gitter chat.
bench/Bench.hsnew file+203
@@ -0,0 +1,203 @@
1+{-# OPTIONS -fno-warn-partial-type-signatures #-}
2+
3+module Main (main) where
4+
5+import Control.DeepSeq
6+import qualified Control.Lens as L
7+import qualified Control.Monad.Reader as M
8+import qualified Control.Monad.State as M
9+import Criterion.Main
10+import Ether
11+import TupleInstances ()
12+
13+id' :: a -> a
14+id' = id
15+{-# NOINLINE id' #-}
16+
17+readerCombinerMTL_flat_9
18+ :: M.MonadReader (Int, Int, Int, Int, Int, Int, Int, Int, Int) m
19+ => m ()
20+readerCombinerMTL_flat_9 = do
21+ rnf <$> sequenceA
22+ [ L.view L._1
23+ , L.view L._2
24+ , L.view L._3
25+ , L.view L._4
26+ , L.view L._5
27+ , L.view L._6
28+ , L.view L._7
29+ , L.view L._8
30+ , L.view L._9 ]
31+{-# NOINLINE readerCombinerMTL_flat_9 #-}
32+
33+stateCombinerMTL_flat_9
34+ :: M.MonadState (Int, Int, Int, Int, Int, Int, Int, Int, Int) m
35+ => m ()
36+stateCombinerMTL_flat_9 = do
37+ M.modify (L.over L._1 id')
38+ M.modify (L.over L._2 id')
39+ M.modify (L.over L._3 id')
40+ M.modify (L.over L._4 id')
41+ M.modify (L.over L._5 id')
42+ M.modify (L.over L._6 id')
43+ M.modify (L.over L._7 id')
44+ M.modify (L.over L._8 id')
45+ M.modify (L.over L._9 id')
46+ rnf <$> sequenceA
47+ [ L.use L._1
48+ , L.use L._2
49+ , L.use L._3
50+ , L.use L._4
51+ , L.use L._5
52+ , L.use L._6
53+ , L.use L._7
54+ , L.use L._8
55+ , L.use L._9 ]
56+{-# NOINLINE stateCombinerMTL_flat_9 #-}
57+
58+run_readerCombinerMTL_flat_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
59+run_readerCombinerMTL_flat_9
60+ (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
61+ M.runReader readerCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
62+
63+run_stateCombinerMTL_flat_9 ::
64+ (Int, Int, Int, Int, Int, Int, Int, Int, Int) ->
65+ ((), (Int, Int, Int, Int, Int, Int, Int, Int, Int))
66+run_stateCombinerMTL_flat_9
67+ (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
68+ M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
69+
70+readerCombinerEther_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 )
80+ => m ()
81+readerCombinerEther_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 ]
91+{-# NOINLINE readerCombinerEther_sep_9 #-}
92+
93+stateCombinerEther_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 )
103+ => m ()
104+stateCombinerEther_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'
114+ 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 #-}
125+
126+run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
127+run_readerCombinerEther_nested_9
128+ (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
138+ $ readerCombinerEther_sep_9
139+
140+run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
141+run_readerCombinerEther_flatten_9
142+ (a1, a2, a3, a4, a5, a6, a7, a8, a9)
143+ =
144+ runReaders
145+ 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 )
155+
156+run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
157+run_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
171+
172+run_stateCombinerEther_flatten_9 ::
173+ (Int, Int, Int, Int, Int, Int, Int, Int, Int) ->
174+ ((), _)
175+run_stateCombinerEther_flatten_9
176+ (a1, a2, a3, a4, a5, a6, a7, a8, a9)
177+ =
178+ runStates
179+ 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 )
189+
190+tuple_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int)
191+tuple_9 = (1, -2, 3, -4, 5, -6, 7, -8, 9)
192+
193+main :: IO ()
194+main = do
195+ defaultMain
196+ [ bench "readerCombinerMTL_flat_9" $ nf run_readerCombinerMTL_flat_9 tuple_9
197+ , bench "readerCombinerEther_nested_9" $ nf run_readerCombinerEther_nested_9 tuple_9
198+ , bench "readerCombinerEther_flatten_9" $ nf run_readerCombinerEther_flatten_9 tuple_9
199+ , bench "readerCombinerEther_flattenhalf_9" $
200+ nf run_readerCombinerEther_flattenhalf_9 tuple_9
201+ , bench "stateCombinerMTL_flat_9" $ nf run_stateCombinerMTL_flat_9 tuple_9
202+ , bench "stateCombinerEther_flatten_9" $ nf run_stateCombinerEther_flatten_9 tuple_9
203+ ]
bench/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module TupleInstances () where
5+
6+#ifdef DISABLE_TUP_INSTANCES
7+import Ether.Internal (makeTupleInstancesHasLens)
8+makeTupleInstancesHasLens [4,5,9]
9+#endif
ether.cabal+219−105
@@ -1,123 +1,237 @@
1+cabal-version: 2.2
12name: ether
2−version: 0.4.0.0
3+version: 0.5.2.0
34synopsis: 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−category: Control
9−license: BSD3
5+description: Lib
6+license: BSD-3-Clause
7+-- ^ unfortunately have to change this line due to the issue with cabal2nix
108license-file: LICENSE
11−author: Index Int
12−maintainer: Index Int <vlad.z.4096@gmail.com>
9+category: Control
10+author: Vladislav Zavialov
11+maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
1312homepage: https://int-index.github.io/ether/
1413bug-reports: https://github.com/int-index/ether/issues
1514build-type: Simple
16−cabal-version: >=1.18
1715extra-source-files: CHANGELOG.md
1816
1917source-repository head
2018
21− type: git
22− location: git@github.com:int-index/ether.git
19+ type: git
20+ location: git@github.com:int-index/ether.git
21+
22+
23+flag disable-tup-instances
2324
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
2436
2537library
2638
27− exposed-modules: Control.Ether.Abbr
28− Control.Ether.Implicit.Abbr
29− Control.Ether.TH
30− Control.Monad.Trans.Ether.Reader
31− Control.Monad.Trans.Ether.Writer
32− Control.Monad.Trans.Ether.State
33− Control.Monad.Trans.Ether.State.Lazy
34− Control.Monad.Trans.Ether.State.Strict
35− Control.Monad.Trans.Ether.Except
36− Control.Monad.Trans.Ether.Dispatch
37− Control.Monad.Ether
38− Control.Monad.Ether.Reader
39− Control.Monad.Ether.Reader.Class
40− Control.Monad.Ether.Writer
41− Control.Monad.Ether.Writer.Class
42− Control.Monad.Ether.State
43− Control.Monad.Ether.State.Class
44− Control.Monad.Ether.State.Lazy
45− Control.Monad.Ether.State.Strict
46− Control.Monad.Ether.Except
47− Control.Monad.Ether.Except.Class
48− Control.Monad.Ether.Implicit
49− Control.Monad.Ether.Implicit.Reader
50− Control.Monad.Ether.Implicit.Writer
51− Control.Monad.Ether.Implicit.State
52− Control.Monad.Ether.Implicit.State.Lazy
53− Control.Monad.Ether.Implicit.State.Strict
54− Control.Monad.Ether.Implicit.Except
55−
56− other-modules: Control.Ether.Util
57−
58− build-depends: base >=4.7 && <4.9
59− , transformers >=0.4.2
60− , transformers-lift >=0.1
61− , mtl >=2.2.1
62− , mmorph >=1.0.4
63− , monad-control >=1.0.0.4
64− , transformers-base >=0.4.4
65− , exceptions >=0.8
66− , template-haskell >=2.9
67−
68− default-language: Haskell2010
69− other-extensions: CPP
70− ConstraintKinds
71− DataKinds
72− DefaultSignatures
73− DeriveGeneric
74− FlexibleInstances
75− FunctionalDependencies
76− GeneralizedNewtypeDeriving
77− MultiParamTypeClasses
78− PolyKinds
79− ScopedTypeVariables
80− TemplateHaskell
81− TypeFamilies
82− TypeOperators
83− UndecidableInstances
84−
85− hs-source-dirs: src
86− ghc-options: -Wall -Werror
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
8769
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
88106
89107test-suite regression
90108
91− build-depends: base >=4.7 && <4.9
92− , transformers >=0.4.2
93− , mtl >=2.2.1
94− , tasty >=0.10
95− , tasty-quickcheck >=0.8
96− , QuickCheck >=2.8
97− , ether
98−
99− main-is: Regression.hs
100− other-modules: Regression.T1
101− Regression.T2
102− Regression.T3
103− Regression.T4
104− Regression.T5
105− Regression.T6
106− Regression.T7
107− Regression.T8
108−
109− type: exitcode-stdio-1.0
110− hs-source-dirs: test
111− default-language: Haskell2010
112− default-extensions: ConstraintKinds
113− DataKinds
114− EmptyDataDecls
115− FlexibleContexts
116− GeneralizedNewtypeDeriving
117− LambdaCase
118− PolyKinds
119− ScopedTypeVariables
120− TemplateHaskell
121− TypeFamilies
122− TypeOperators
123− ghc-options: -Wall -Werror -fno-warn-missing-signatures
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
shell.nixnew file+22
@@ -0,0 +1,22 @@
1+{ pkgs ? import <nixpkgs> {},
2+ hc ? "ghc844"
3+}:
4+
5+pkgs.stdenv.mkDerivation rec {
6+ name = "ether";
7+ buildInputs = [
8+ pkgs.haskell.compiler.${hc}
9+ pkgs.git
10+ pkgs.zlib
11+ pkgs.cabal-install
12+ pkgs.pkgconfig
13+ ];
14+ shellHook = ''
15+ export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH
16+ export LANG=en_US.UTF-8
17+ '';
18+ LOCALE_ARCHIVE =
19+ if pkgs.stdenv.isLinux
20+ then "${pkgs.glibcLocales}/lib/locale/locale-archive"
21+ else "";
22+}
src/Control/Ether/Abbr.hsdeleted−60
@@ -1,60 +0,0 @@
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)
src/Control/Ether/Implicit/Abbr.hsdeleted−25
@@ -1,25 +0,0 @@
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−
src/Control/Ether/TH.hsdeleted−40
@@ -1,40 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−-- | Template Haskell utilities.
4−
5−module Control.Ether.TH
6− ( ethereal
7− ) where
8−
9−import qualified Language.Haskell.TH as TH
10−
11−import Data.Proxy
12−
13−emptyDataDecl :: TH.Name -> TH.DecQ
14−emptyDataDecl name = TH.dataD (return []) name [] [] []
15−
16−funSimple :: TH.Name -> TH.ExpQ -> TH.DecQ
17−funSimple name body = TH.funD name [ TH.clause [] (TH.normalB body) [] ]
18−
19−proxySimple :: TH.Name -> TH.TypeQ -> TH.Q (TH.Dec, TH.Dec)
20−proxySimple name ty = do
21− sig <- TH.sigD name [t| Proxy $ty |]
22− val <- funSimple name [e| Proxy |]
23− return (sig, val)
24−
25−-- |
26−-- Creates a tag and a value-level proxy for it.
27−--
28−-- @'ethereal' \"Foo\" \"foo\"@ generates the following code:
29−--
30−-- > data Foo
31−-- > foo :: Proxy Foo
32−-- > foo = Proxy
33−ethereal :: String -> String -> TH.DecsQ
34−ethereal strTagName strTagProxyName = do
35− let tagName = TH.mkName strTagName
36− tag = TH.conT tagName
37− tagProxyName = TH.mkName strTagProxyName
38− tagDecl <- emptyDataDecl tagName
39− (tagProxySig, tagProxyVal) <- proxySimple tagProxyName tag
40− return [tagDecl, tagProxySig, tagProxyVal]
src/Control/Ether/Util.hsdeleted−22
@@ -1,22 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−module Control.Ether.Util
3− ( fmap
4− ) where
5−
6−import Prelude hiding (fmap)
7−
8−#if __GLASGOW_HASKELL__ < 710
9−import qualified Control.Monad
10−#else
11−import qualified Prelude
12−#endif
13−
14−#if __GLASGOW_HASKELL__ < 710
15−fmap :: Monad f => (a -> b) -> f a -> f b
16−fmap = Control.Monad.liftM
17−#else
18−fmap :: Functor f => (a -> b) -> f a -> f b
19−fmap = Prelude.fmap
20−#endif
21−
22−{-# INLINE fmap #-}
src/Control/Monad/Ether.hsdeleted−14
@@ -1,14 +0,0 @@
1−
2−-- | This module provides convenience exports of all
3−-- tagged monad classes from Ether.
4−
5−module Control.Monad.Ether (module X) where
6−
7−import Control.Monad as X
8−import Control.Monad.Fix as X
9−import Control.Monad.Ether.Reader as X
10−import Control.Monad.Ether.Writer as X
11−import Control.Monad.Ether.State as X
12−import Control.Monad.Ether.Except as X
13−import Control.Monad.Trans.Ether.Dispatch as X hiding (pack, unpack)
14−import Control.Ether.TH as X (ethereal)
src/Control/Monad/Ether/Except.hsdeleted−30
@@ -1,30 +0,0 @@
1−
2−-- | See "Control.Monad.Except".
3−
4−module Control.Monad.Ether.Except
5− (
6− -- * MonadExcept class
7− MonadExcept(..)
8− -- * The Except monad
9− , Except
10− , runExcept
11− -- * The ExceptT monad transformer
12− , ExceptT
13− , exceptT
14− , runExceptT
15− -- * Handle functions
16− , handleT
17− , handle
18− ) where
19−
20−import Control.Monad.Ether.Except.Class
21−import Control.Monad.Trans.Ether.Except hiding (throw, catch)
22−import Data.Functor.Identity (Identity(..))
23−
24−-- | Runs an 'Except' and handles the exception with the given function.
25−handle :: proxy tag -> (e -> a) -> Except tag e a -> a
26−handle t h m = runIdentity (handleT t h m)
27−
28−-- | Runs an 'ExceptT' and handles the exception with the given function.
29−handleT :: Functor m => proxy tag -> (e -> a) -> ExceptT tag e m a -> m a
30−handleT t h m = fmap (either h id) (runExceptT t m)
src/Control/Monad/Ether/Except/Class.hsdeleted−44
@@ -1,44 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−#if __GLASGOW_HASKELL__ < 710
4−{-# LANGUAGE OverlappingInstances #-}
5−{-# OPTIONS_GHC -fno-warn-unrecognised-pragmas #-}
6−#endif
7−
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE FlexibleInstances #-}
10−{-# LANGUAGE UndecidableInstances #-}
11−{-# LANGUAGE FunctionalDependencies #-}
12−{-# LANGUAGE PolyKinds #-}
13−
14−-- | See "Control.Monad.Except".
15−
16−module Control.Monad.Ether.Except.Class
17− ( MonadExcept(..)
18− ) where
19−
20−import qualified Control.Monad.Trans.Ether.Except as E
21−import qualified Control.Monad.Trans.Lift.Catch as Lift
22−
23−
24−-- | See 'Control.Monad.Except.MonadError'.
25−class Monad m => MonadExcept tag e m | m tag -> e where
26−
27− -- | Is used within a monadic computation to begin exception processing.
28− throw :: proxy tag -> e -> m a
29−
30− -- | A handler function to handle previous exceptions and return to
31− -- normal execution.
32− catch :: proxy tag -> m a -> (e -> m a) -> m a
33−
34−instance Monad m => MonadExcept tag e (E.ExceptT tag e m) where
35− throw = E.throw
36− catch = E.catch
37−
38−instance {-# OVERLAPPABLE #-}
39− ( Lift.LiftCatch t
40− , Monad (t m)
41− , MonadExcept tag e m
42− ) => MonadExcept tag e (t m) where
43− throw t = Lift.lift . throw t
44− catch t = Lift.liftCatch (catch t)
src/Control/Monad/Ether/Implicit.hsdeleted−14
@@ -1,14 +0,0 @@
1−
2−-- | This module provides convenience exports of all
3−-- implicitly tagged monad classes from Ether.
4−
5−module Control.Monad.Ether.Implicit (module X) where
6−
7−import Control.Monad as X
8−import Control.Monad.Fix as X
9−import Control.Monad.Ether.Implicit.Reader as X
10−import Control.Monad.Ether.Implicit.Writer as X
11−import Control.Monad.Ether.Implicit.State as X
12−import Control.Monad.Ether.Implicit.Except as X
13−import Control.Monad.Trans.Ether.Dispatch as X hiding (pack, unpack)
14−import Control.Ether.TH as X (ethereal)
src/Control/Monad/Ether/Implicit/Except.hsdeleted−62
@@ -1,62 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | See "Control.Monad.Ether.Except".
5−
6−module Control.Monad.Ether.Implicit.Except
7− (
8− -- * MonadExcept class
9− MonadExcept
10− , throw
11− , catch
12− -- * The Except monad
13− , Except
14− , runExcept
15− -- * The ExceptT monad transformer
16− , ExceptT
17− , exceptT
18− , runExceptT
19− -- * Handle functions
20− , handle
21− , handleT
22− ) where
23−
24−import Data.Proxy
25−import qualified Control.Monad.Ether.Except as Explicit
26−
27−-- | See 'Control.Monad.Ether.Except.MonadExcept'.
28−type MonadExcept e = Explicit.MonadExcept e e
29−
30−-- | See 'Control.Monad.Ether.Except.throw'.
31−throw :: forall e m a . MonadExcept e m => e -> m a
32−throw = Explicit.throw (Proxy :: Proxy e)
33−
34−-- | See 'Control.Monad.Ether.Except.catch'.
35−catch :: forall e m a . MonadExcept e m => m a -> (e -> m a) -> m a
36−catch = Explicit.catch (Proxy :: Proxy e)
37−
38−-- | See 'Control.Monad.Ether.Except.Except'.
39−type Except e = Explicit.Except e e
40−
41−-- | See 'Control.Monad.Ether.Except.runExcept'.
42−runExcept :: Except e a -> Either e a
43−runExcept = Explicit.runExcept Proxy
44−
45−-- | See 'Control.Monad.Ether.Except.ExceptT'.
46−type ExceptT e = Explicit.ExceptT e e
47−
48−-- | See 'Control.Monad.Ether.Except.exceptT'.
49−exceptT :: m (Either e a) -> ExceptT e m a
50−exceptT = Explicit.exceptT Proxy
51−
52−-- | See 'Control.Monad.Ether.Except.runExceptT'.
53−runExceptT :: ExceptT e m a -> m (Either e a)
54−runExceptT = Explicit.runExceptT Proxy
55−
56−-- | See 'Control.Monad.Ether.Except.handle'.
57−handle :: (e -> a) -> Except e a -> a
58−handle = Explicit.handle (Proxy :: Proxy e)
59−
60−-- | See 'Control.Monad.Ether.Except.handleT'.
61−handleT :: Functor m => (e -> a) -> ExceptT e m a -> m a
62−handleT = Explicit.handleT (Proxy :: Proxy e)
src/Control/Monad/Ether/Implicit/Reader.hsdeleted−61
@@ -1,61 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | See "Control.Monad.Ether.Reader".
5−
6−module Control.Monad.Ether.Implicit.Reader
7− (
8− -- * MonadReader class
9− MonadReader
10− , local
11− , ask
12− , reader
13− , asks
14− -- * The Reader monad
15− , Reader
16− , runReader
17− -- * The ReaderT monad transformer
18− , ReaderT
19− , readerT
20− , runReaderT
21− ) where
22−
23−import Data.Proxy
24−import qualified Control.Monad.Ether.Reader as Explicit
25−
26−-- | See 'Control.Monad.Ether.Reader.ReaderT'.
27−type ReaderT r = Explicit.ReaderT r r
28−
29−-- | See 'Control.Monad.Ether.Reader.Reader'.
30−type Reader r = Explicit.Reader r r
31−
32−-- | See 'Control.Monad.Ether.Reader.readerT'.
33−readerT :: (r -> m a) -> ReaderT r m a
34−readerT = Explicit.readerT Proxy
35−
36−-- | See 'Control.Monad.Ether.Reader.runReaderT'.
37−runReaderT :: ReaderT r m a -> r -> m a
38−runReaderT = Explicit.runReaderT Proxy
39−
40−-- | See 'Control.Monad.Ether.Reader.runReader'.
41−runReader :: Reader r a -> r -> a
42−runReader = Explicit.runReader Proxy
43−
44−-- | See 'Control.Monad.Ether.Reader.MonadReader'.
45−type MonadReader r = Explicit.MonadReader r r
46−
47−-- | See 'Control.Monad.Ether.Reader.local'.
48−local :: forall m r a . MonadReader r m => (r -> r) -> m a -> m a
49−local = Explicit.local (Proxy :: Proxy r)
50−
51−-- | See 'Control.Monad.Ether.Reader.ask'.
52−ask :: forall m r . MonadReader r m => m r
53−ask = Explicit.ask (Proxy :: Proxy r)
54−
55−-- | See 'Control.Monad.Ether.Reader.reader'.
56−reader :: forall m r a . MonadReader r m => (r -> a) -> m a
57−reader = Explicit.reader (Proxy :: Proxy r)
58−
59−-- | See 'Control.Monad.Ether.Reader.asks'.
60−asks :: forall m r a . MonadReader r m => (r -> a) -> m a
61−asks = Explicit.asks (Proxy :: Proxy r)
src/Control/Monad/Ether/Implicit/State.hsdeleted−8
@@ -1,8 +0,0 @@
1−
2−-- | See "Control.Monad.Ether.State".
3−
4−module Control.Monad.Ether.Implicit.State
5− ( module Control.Monad.Ether.Implicit.State.Lazy
6− ) where
7−
8−import Control.Monad.Ether.Implicit.State.Lazy
src/Control/Monad/Ether/Implicit/State/Lazy.hsdeleted−86
@@ -1,86 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | See "Control.Monad.Ether.State.Lazy".
5−
6−module Control.Monad.Ether.Implicit.State.Lazy
7− (
8− -- * MonadState class
9− MonadState
10− , get
11− , put
12− , state
13− , modify
14− , gets
15− -- * The State monad
16− , State
17− , runState
18− , evalState
19− , execState
20− -- * The StateT monad transformer
21− , StateT
22− , stateT
23− , runStateT
24− , evalStateT
25− , execStateT
26− ) where
27−
28−import Data.Proxy
29−import qualified Control.Monad.Ether.State.Lazy as Explicit
30−
31−-- | See 'Control.Monad.Ether.State.Lazy.StateT'.
32−type StateT s = Explicit.StateT s s
33−
34−-- | See 'Control.Monad.Ether.State.Lazy.State'.
35−type State s = Explicit.State s s
36−
37−-- | See 'Control.Monad.Ether.State.Lazy.stateT'.
38−stateT :: (s -> m (a, s)) -> StateT s m a
39−stateT = Explicit.stateT Proxy
40−
41−-- | See 'Control.Monad.Ether.State.Lazy.runStateT'.
42−runStateT :: StateT s m a -> s -> m (a, s)
43−runStateT = Explicit.runStateT Proxy
44−
45−-- | See 'Control.Monad.Ether.State.Lazy.runState'.
46−runState :: State s a -> s -> (a, s)
47−runState = Explicit.runState Proxy
48−
49−-- | See 'Control.Monad.Ether.State.Lazy.evalStateT'.
50−evalStateT :: Monad m => StateT s m a -> s -> m a
51−evalStateT = Explicit.evalStateT Proxy
52−
53−-- | See 'Control.Monad.Ether.State.Lazy.evalState'.
54−evalState :: State s a -> s -> a
55−evalState = Explicit.evalState Proxy
56−
57−-- | See 'Control.Monad.Ether.State.Lazy.execStateT'.
58−execStateT :: Monad m => StateT s m a -> s -> m s
59−execStateT = Explicit.execStateT Proxy
60−
61−-- | See 'Control.Monad.Ether.State.Lazy.execState'.
62−execState :: State s a -> s -> s
63−execState = Explicit.execState Proxy
64−
65−-- | See 'Control.Monad.Ether.State.Lazy.MonadState'.
66−type MonadState s = Explicit.MonadState s s
67−
68−-- | See 'Control.Monad.Ether.State.Lazy.get'.
69−get :: forall m s . MonadState s m => m s
70−get = Explicit.get (Proxy :: Proxy s)
71−
72−-- | See 'Control.Monad.Ether.State.Lazy.gets'.
73−gets :: forall m s a . MonadState s m => (s -> a) -> m a
74−gets = Explicit.gets (Proxy :: Proxy s)
75−
76−-- | See 'Control.Monad.Ether.State.Lazy.put'.
77−put :: forall m s . MonadState s m => s -> m ()
78−put = Explicit.put (Proxy :: Proxy s)
79−
80−-- | See 'Control.Monad.Ether.State.Lazy.state'.
81−state :: forall m s a . MonadState s m => (s -> (a, s)) -> m a
82−state = Explicit.state (Proxy :: Proxy s)
83−
84−-- | See 'Control.Monad.Ether.State.Lazy.modify'.
85−modify :: forall m s . MonadState s m => (s -> s) -> m ()
86−modify = Explicit.modify (Proxy :: Proxy s)
src/Control/Monad/Ether/Implicit/State/Strict.hsdeleted−86
@@ -1,86 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | See "Control.Monad.Ether.State.Strict".
5−
6−module Control.Monad.Ether.Implicit.State.Strict
7− (
8− -- * MonadState class
9− MonadState
10− , get
11− , put
12− , state
13− , modify
14− , gets
15− -- * The State monad
16− , State
17− , runState
18− , evalState
19− , execState
20− -- * The StateT monad transformer
21− , StateT
22− , stateT
23− , runStateT
24− , evalStateT
25− , execStateT
26− ) where
27−
28−import Data.Proxy
29−import qualified Control.Monad.Ether.State.Strict as Explicit
30−
31−-- | See 'Control.Monad.Ether.State.Strict.StateT'.
32−type StateT s = Explicit.StateT s s
33−
34−-- | See 'Control.Monad.Ether.State.Strict.State'.
35−type State s = Explicit.State s s
36−
37−-- | See 'Control.Monad.Ether.State.Strict.stateT'.
38−stateT :: (s -> m (a, s)) -> StateT s m a
39−stateT = Explicit.stateT Proxy
40−
41−-- | See 'Control.Monad.Ether.State.Strict.runStateT'.
42−runStateT :: StateT s m a -> s -> m (a, s)
43−runStateT = Explicit.runStateT Proxy
44−
45−-- | See 'Control.Monad.Ether.State.Strict.runState'.
46−runState :: State s a -> s -> (a, s)
47−runState = Explicit.runState Proxy
48−
49−-- | See 'Control.Monad.Ether.State.Strict.evalStateT'.
50−evalStateT :: Monad m => StateT s m a -> s -> m a
51−evalStateT = Explicit.evalStateT Proxy
52−
53−-- | See 'Control.Monad.Ether.State.Strict.evalState'.
54−evalState :: State s a -> s -> a
55−evalState = Explicit.evalState Proxy
56−
57−-- | See 'Control.Monad.Ether.State.Strict.execStateT'.
58−execStateT :: Monad m => StateT s m a -> s -> m s
59−execStateT = Explicit.execStateT Proxy
60−
61−-- | See 'Control.Monad.Ether.State.Strict.execState'.
62−execState :: State s a -> s -> s
63−execState = Explicit.execState Proxy
64−
65−-- | See 'Control.Monad.Ether.State.Strict.MonadState'.
66−type MonadState s = Explicit.MonadState s s
67−
68−-- | See 'Control.Monad.Ether.State.Strict.get'.
69−get :: forall m s . MonadState s m => m s
70−get = Explicit.get (Proxy :: Proxy s)
71−
72−-- | See 'Control.Monad.Ether.State.Strict.gets'.
73−gets :: forall m s a . MonadState s m => (s -> a) -> m a
74−gets = Explicit.gets (Proxy :: Proxy s)
75−
76−-- | See 'Control.Monad.Ether.State.Strict.put'.
77−put :: forall m s . MonadState s m => s -> m ()
78−put = Explicit.put (Proxy :: Proxy s)
79−
80−-- | See 'Control.Monad.Ether.State.Strict.state'.
81−state :: forall m s a . MonadState s m => (s -> (a, s)) -> m a
82−state = Explicit.state (Proxy :: Proxy s)
83−
84−-- | See 'Control.Monad.Ether.State.Strict.modify'.
85−modify :: forall m s . MonadState s m => (s -> s) -> m ()
86−modify = Explicit.modify (Proxy :: Proxy s)
src/Control/Monad/Ether/Implicit/Writer.hsdeleted−81
@@ -1,81 +0,0 @@
1−{-# LANGUAGE ConstraintKinds #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | See "Control.Monad.Ether.Writer".
5−
6−module Control.Monad.Ether.Implicit.Writer
7− (
8− -- * MonadWriter class
9− MonadWriter
10− , writer
11− , tell
12− , listen
13− , pass
14− , listens
15− , censor
16− -- * The Writer monad
17− , Writer
18− , runWriter
19− , execWriter
20− -- * The WriterT monad transformer
21− , WriterT
22− , writerT
23− , runWriterT
24− , execWriterT
25− ) where
26−
27−import Data.Proxy
28−import qualified Control.Monad.Ether.Writer as Explicit
29−
30−-- | See 'Control.Monad.Ether.Writer.MonadWriter'.
31−type MonadWriter w = Explicit.MonadWriter w w
32−
33−-- | See 'Control.Monad.Ether.Writer.writer'.
34−writer :: forall m w a . MonadWriter w m => (a, w) -> m a
35−writer = Explicit.writer (Proxy :: Proxy w)
36−
37−-- | See 'Control.Monad.Ether.Writer.tell'.
38−tell :: forall m w . MonadWriter w m => w -> m ()
39−tell = Explicit.tell (Proxy :: Proxy w)
40−
41−-- | See 'Control.Monad.Ether.Writer.listen'.
42−listen :: forall m w a . MonadWriter w m => m a -> m (a, w)
43−listen = Explicit.listen (Proxy :: Proxy w)
44−
45−-- | See 'Control.Monad.Ether.Writer.pass'.
46−pass :: forall m w a . MonadWriter w m => m (a, w -> w) -> m a
47−pass = Explicit.pass (Proxy :: Proxy w)
48−
49−-- | See 'Control.Monad.Ether.Writer.listens'.
50−listens :: forall m w a b . MonadWriter w m => (w -> b) -> m a -> m (a, b)
51−listens = Explicit.listens (Proxy :: Proxy w)
52−
53−-- | See 'Control.Monad.Ether.Writer.censor'.
54−censor :: forall m w a . MonadWriter w m => (w -> w) -> m a -> m a
55−censor = Explicit.censor (Proxy :: Proxy w)
56−
57−-- | See 'Control.Monad.Ether.Writer.Writer'.
58−type Writer w = Explicit.Writer w w
59−
60−-- | See 'Control.Monad.Ether.Writer.runWriter'.
61−runWriter :: Writer w a -> (a, w)
62−runWriter = Explicit.runWriter Proxy
63−
64−-- | See 'Control.Monad.Ether.Writer.execWriter'.
65−execWriter :: Writer w a -> w
66−execWriter = Explicit.execWriter Proxy
67−
68−-- | See 'Control.Monad.Ether.Writer.WriterT'.
69−type WriterT w = Explicit.WriterT w w
70−
71−-- | See 'Control.Monad.Ether.Writer.writerT'.
72−writerT :: m (a, w) -> WriterT w m a
73−writerT = Explicit.writerT Proxy
74−
75−-- | See 'Control.Monad.Ether.Writer.runWriterT'.
76−runWriterT :: WriterT w m a -> m (a, w)
77−runWriterT = Explicit.runWriterT Proxy
78−
79−-- | See 'Control.Monad.Ether.Writer.execWriterT'.
80−execWriterT :: Monad m => WriterT w m a -> m w
81−execWriterT = Explicit.execWriterT Proxy
src/Control/Monad/Ether/Reader.hsdeleted−19
@@ -1,19 +0,0 @@
1−
2−-- | See "Control.Monad.Reader".
3−
4−module Control.Monad.Ether.Reader
5− (
6− -- * MonadReader class
7− MonadReader(..)
8− , asks
9− -- * The Reader monad
10− , Reader
11− , runReader
12− -- * The ReaderT monad transformer
13− , ReaderT
14− , readerT
15− , runReaderT
16− ) where
17−
18−import Control.Monad.Ether.Reader.Class
19−import Control.Monad.Trans.Ether.Reader hiding (reader, ask, local)
src/Control/Monad/Ether/Reader/Class.hsdeleted−71
@@ -1,71 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−#if __GLASGOW_HASKELL__ < 710
4−{-# LANGUAGE OverlappingInstances #-}
5−{-# OPTIONS_GHC -fno-warn-unrecognised-pragmas #-}
6−#endif
7−
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE FlexibleInstances #-}
10−{-# LANGUAGE UndecidableInstances #-}
11−{-# LANGUAGE FunctionalDependencies #-}
12−{-# LANGUAGE PolyKinds #-}
13−
14−-- | See "Control.Monad.Reader.Class".
15−
16−module Control.Monad.Ether.Reader.Class
17− ( MonadReader(..)
18− , asks
19− ) where
20−
21−import qualified Control.Monad.Trans.Ether.Reader as R
22−import qualified Control.Monad.Trans.Lift.Local as Lift
23−import qualified Control.Ether.Util as Util
24−
25−-- | See 'Control.Monad.Reader.MonadReader'.
26−class Monad m => MonadReader tag r m | m tag -> r where
27−
28− {-# MINIMAL (ask | reader), local #-}
29−
30− -- | Retrieves the monad environment.
31− ask :: proxy tag -> m r
32− ask t = reader t id
33−
34− -- | Executes a computation in a modified environment.
35− local
36− :: proxy tag
37− -> (r -> r)
38− -- ^ The function to modify the environment.
39− -> m a
40− -- ^ @Reader@ to run in the modified environment.
41− -> m a
42−
43− -- | Retrieves a function of the current environment.
44− reader
45− :: proxy tag
46− -> (r -> a)
47− -- ^ The selector function to apply to the environment.
48− -> m a
49− reader t f = Util.fmap f (ask t)
50−
51−-- | Retrieves a function of the current environment.
52−asks
53− :: MonadReader tag r m
54− => proxy tag
55− -> (r -> a)
56− -- ^ The selector function to apply to the environment.
57− -> m a
58−asks = reader
59−
60−instance Monad m => MonadReader tag r (R.ReaderT tag r m) where
61− ask = R.ask
62− local = R.local
63− reader = R.reader
64−
65−instance {-# OVERLAPPABLE #-}
66− ( Lift.LiftLocal t
67− , Monad (t m)
68− , MonadReader tag r m
69− ) => MonadReader tag r (t m) where
70− ask t = Lift.lift (ask t)
71− local t = Lift.liftLocal (ask t) (local t)
src/Control/Monad/Ether/State.hsdeleted−8
@@ -1,8 +0,0 @@
1−
2−-- | See "Control.Monad.State".
3−
4−module Control.Monad.Ether.State
5− ( module Control.Monad.Ether.State.Lazy
6− ) where
7−
8−import Control.Monad.Ether.State.Lazy
src/Control/Monad/Ether/State/Class.hsdeleted−73
@@ -1,73 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−#if __GLASGOW_HASKELL__ < 710
4−{-# LANGUAGE OverlappingInstances #-}
5−{-# OPTIONS_GHC -fno-warn-unrecognised-pragmas #-}
6−#endif
7−
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE FlexibleInstances #-}
10−{-# LANGUAGE UndecidableInstances #-}
11−{-# LANGUAGE FunctionalDependencies #-}
12−{-# LANGUAGE PolyKinds #-}
13−
14−-- | See "Control.Monad.State.Class".
15−
16−module Control.Monad.Ether.State.Class
17− ( MonadState(..)
18− , modify
19− , gets
20− ) where
21−
22−import qualified Control.Monad.Trans.Ether.State.Lazy as S.L
23−import qualified Control.Monad.Trans.Ether.State.Strict as S.S
24−import qualified Control.Monad.Trans as Lift
25−import qualified Control.Ether.Util as Util
26−
27−-- | See 'Control.Monad.State.MonadState'.
28−class Monad m => MonadState tag s m | m tag -> s where
29−
30− {-# MINIMAL state | get, put #-}
31−
32− -- | Return the state from the internals of the monad.
33− get :: proxy tag -> m s
34− get t = state t (\s -> (s, s))
35−
36− -- | Replace the state inside the monad.
37− put :: proxy tag -> s -> m ()
38− put t s = state t (\_ -> ((), s))
39−
40− -- | Embed a simple state action into the monad.
41− state :: proxy tag -> (s -> (a, s)) -> m a
42− state t f = do
43− s <- get t
44− let ~(a, s') = f s
45− put t s'
46− return a
47−
48−-- | Modifies the state inside a state monad.
49−modify :: MonadState tag s m => proxy tag -> (s -> s) -> m ()
50−modify t f = state t (\s -> ((), f s))
51−
52−-- | Gets specific component of the state, using a projection function supplied.
53−gets :: MonadState tag s m => proxy tag -> (s -> a) -> m a
54−gets t f = Util.fmap f (get t)
55−
56−instance Monad m => MonadState tag s (S.L.StateT tag s m) where
57− get = S.L.get
58− put = S.L.put
59− state = S.L.state
60−
61−instance Monad m => MonadState tag s (S.S.StateT tag s m) where
62− get = S.S.get
63− put = S.S.put
64− state = S.S.state
65−
66−instance {-# OVERLAPPABLE #-}
67− ( Lift.MonadTrans t
68− , Monad (t m)
69− , MonadState tag s m
70− ) => MonadState tag s (t m) where
71− get t = Lift.lift (get t)
72− put t = Lift.lift . put t
73− state t = Lift.lift . state t
src/Control/Monad/Ether/State/Lazy.hsdeleted−24
@@ -1,24 +0,0 @@
1−
2−-- | See "Control.Monad.State.Lazy".
3−
4−module Control.Monad.Ether.State.Lazy
5− (
6− -- * MonadState class
7− MonadState(..)
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− ) where
22−
23−import Control.Monad.Ether.State.Class
24−import Control.Monad.Trans.Ether.State.Lazy hiding (state, get, put)
src/Control/Monad/Ether/State/Strict.hsdeleted−24
@@ -1,24 +0,0 @@
1−
2−-- | See "Control.Monad.State.Strict".
3−
4−module Control.Monad.Ether.State.Strict
5− (
6− -- * MonadState class
7− MonadState(..)
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− ) where
22−
23−import Control.Monad.Ether.State.Class
24−import Control.Monad.Trans.Ether.State.Strict hiding (state, get, put)
src/Control/Monad/Ether/Writer.hsdeleted−22
@@ -1,22 +0,0 @@
1−
2−-- | See "Control.Monad.Writer".
3−
4−module Control.Monad.Ether.Writer
5− (
6− -- * MonadWriter class
7− MonadWriter(..)
8− , listens
9− , censor
10− -- * The Writer monad
11− , Writer
12− , runWriter
13− , execWriter
14− -- * The WriterT monad transformer
15− , WriterT
16− , writerT
17− , runWriterT
18− , execWriterT
19− ) where
20−
21−import Control.Monad.Ether.Writer.Class
22−import Control.Monad.Trans.Ether.Writer hiding (writer, tell, listen, pass)
src/Control/Monad/Ether/Writer/Class.hsdeleted−82
@@ -1,82 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−#if __GLASGOW_HASKELL__ < 710
4−{-# LANGUAGE OverlappingInstances #-}
5−{-# OPTIONS_GHC -fno-warn-unrecognised-pragmas #-}
6−#endif
7−
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE FlexibleInstances #-}
10−{-# LANGUAGE UndecidableInstances #-}
11−{-# LANGUAGE FunctionalDependencies #-}
12−{-# LANGUAGE PolyKinds #-}
13−
14−-- | See "Control.Monad.Writer.Class".
15−
16−module Control.Monad.Ether.Writer.Class
17− ( MonadWriter(..)
18− , listens
19− , censor
20− ) where
21−
22−#if __GLASGOW_HASKELL__ < 710
23−import Data.Monoid
24−#endif
25−
26−import qualified Control.Monad.Trans.Ether.Writer as W
27−import qualified Control.Monad.Trans.Lift.Listen as Lift
28−import qualified Control.Monad.Trans.Lift.Pass as Lift
29−
30−-- | See 'Control.Monad.Writer.MonadWriter'.
31−class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
32−
33− {-# MINIMAL (writer | tell), listen, pass #-}
34−
35− -- | Embed a simple writer action.
36− writer :: proxy tag -> (a, w) -> m a
37− writer t ~(a, w) = do
38− tell t w
39− return a
40−
41− -- | Append a value to the accumulator within the monad.
42− tell :: proxy tag -> w -> m ()
43− tell t w = writer t ((),w)
44−
45− -- | Execute an action and add its accumulator
46− -- to the value of the computation.
47− listen :: proxy tag -> m a -> m (a, w)
48−
49− -- | Execute an action which returns a value and a function,
50− -- and return the value, applying the function to the accumulator.
51− pass :: proxy tag -> m (a, w -> w) -> m a
52−
53−-- | Execute an action and add the result of applying the given function to
54−-- its accumulator to the value of the computation.
55−listens :: MonadWriter tag w m => proxy tag -> (w -> b) -> m a -> m (a, b)
56−listens t f m = do
57− ~(a, w) <- listen t m
58− return (a, f w)
59−
60−-- | Execute an action and apply a function to its accumulator.
61−censor :: MonadWriter tag w m => proxy tag -> (w -> w) -> m a -> m a
62−censor t f m = pass t $ do
63− a <- m
64− return (a, f)
65−
66−instance (Monoid w, Monad m) => MonadWriter tag w (W.WriterT tag w m) where
67− writer = W.writer
68− tell = W.tell
69− listen = W.listen
70− pass = W.pass
71−
72−instance {-# OVERLAPPABLE #-}
73− ( Lift.LiftListen t
74− , Lift.LiftPass t
75− , Monad (t m)
76− , MonadWriter tag w m
77− , Monoid w
78− ) => MonadWriter tag w (t m) where
79− writer t = Lift.lift . writer t
80− tell t = Lift.lift . tell t
81− listen t = Lift.liftListen (listen t)
82− pass t = Lift.liftPass (pass t)
src/Control/Monad/Trans/Ether/Dispatch.hsdeleted−184
@@ -1,184 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−#if __GLASGOW_HASKELL__ >= 710
4−{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}
5−#endif
6−
7−{-# LANGUAGE DeriveGeneric #-}
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE TypeFamilies #-}
10−{-# LANGUAGE FlexibleInstances #-}
11−{-# LANGUAGE UndecidableInstances #-}
12−{-# LANGUAGE ScopedTypeVariables #-}
13−{-# LANGUAGE DataKinds #-}
14−{-# LANGUAGE PolyKinds #-}
15−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
16−
17−{- |
18−
19−-}
20−
21−module Control.Monad.Trans.Ether.Dispatch
22− (
23− -- * The DispatchT monad transformer
24− DispatchT
25− -- * Dispatch types and functions
26− , K_TagAttach(..)
27− , K_TagReplace(..)
28− , tagAttach
29− , tagReplace
30− -- * Newtype operations
31− , pack
32− , unpack
33− ) where
34−
35−import Control.Applicative
36−import Control.Monad (MonadPlus)
37−import Control.Monad.Fix (MonadFix)
38−import Control.Monad.Trans.Class (MonadTrans)
39−import Control.Monad.IO.Class (MonadIO)
40−import Control.Monad.Morph (MFunctor, MMonad)
41−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
42−import GHC.Generics (Generic)
43−import Data.Coerce (coerce)
44−import Data.Proxy
45−
46−import qualified Control.Monad.Base as MB
47−import qualified Control.Monad.Trans.Control as MC
48−import qualified Control.Monad.Trans.Identity as Trans
49−
50−import qualified Control.Monad.Trans.Lift.StT as Lift
51−import qualified Control.Monad.Trans.Lift.Local as Lift
52−import qualified Control.Monad.Trans.Lift.Catch as Lift
53−import qualified Control.Monad.Trans.Lift.Listen as Lift
54−import qualified Control.Monad.Trans.Lift.Pass as Lift
55−import qualified Control.Monad.Trans.Lift.CallCC as Lift
56−
57−import Control.Monad.Ether.Reader.Class
58−import Control.Monad.Ether.State.Class
59−import Control.Monad.Ether.Except.Class
60−import Control.Monad.Ether.Writer.Class
61−
62−import qualified Control.Monad.Reader as Class
63−import qualified Control.Monad.State as Class
64−import qualified Control.Monad.Except as Class
65−import qualified Control.Monad.Writer as Class
66−
67−-- | Encode type-level information for 'tagAttach'.
68−data K_TagAttach t = TagAttach t
69−
70−-- | Encode type-level information for 'tagReplace'.
71−data K_TagReplace tOld tNew = TagReplace tOld tNew
72−
73−-- | Wrap a monad to change its tags. Under the hood this is
74−-- simply 'Trans.IdentityT', all the work is happening on the type level.
75−newtype DispatchT dp m a = DispatchT (Trans.IdentityT m a)
76− deriving
77− ( Generic
78− , Functor, Applicative, Alternative, Monad, MonadPlus
79− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
80− , MonadThrow, MonadCatch, MonadMask )
81−
82−type DispatchTagAttachT t = DispatchT (TagAttach t)
83−type DispatchTagReplaceT tOld tNew = DispatchT (TagReplace tOld tNew)
84−
85−-- | Type-restricted 'coerce'.
86−pack :: Trans.IdentityT m a -> DispatchT dp m a
87−pack = coerce
88−
89−-- | Type-restricted 'coerce'.
90−unpack :: DispatchT dp m a -> Trans.IdentityT m a
91−unpack = coerce
92−
93−instance MB.MonadBase b m => MB.MonadBase b (DispatchT dp m) where
94− liftBase = MB.liftBaseDefault
95−
96−instance MC.MonadTransControl (DispatchT dp) where
97− type StT (DispatchT dp) a = MC.StT Trans.IdentityT a
98− liftWith = MC.defaultLiftWith pack unpack
99− restoreT = MC.defaultRestoreT pack
100−
101−instance MC.MonadBaseControl b m => MC.MonadBaseControl b (DispatchT dp m) where
102− type StM (DispatchT dp m) a = MC.ComposeSt (DispatchT dp) m a
103− liftBaseWith = MC.defaultLiftBaseWith
104− restoreM = MC.defaultRestoreM
105−
106−type instance Lift.StT (DispatchT dp) a = MC.StT (DispatchT dp) a
107−
108−instance Lift.LiftLocal (DispatchT dp) where
109− liftLocal = Lift.defaultLiftLocal pack unpack
110−
111−instance Lift.LiftCatch (DispatchT dp) where
112− liftCatch = Lift.defaultLiftCatch pack unpack
113−
114−instance Lift.LiftListen (DispatchT dp) where
115− liftListen = Lift.defaultLiftListen pack unpack
116−
117−instance Lift.LiftPass (DispatchT dp) where
118− liftPass = Lift.defaultLiftPass pack unpack
119−
120−instance Lift.LiftCallCC (DispatchT dp) where
121− liftCallCC = Lift.defaultLiftCallCC pack unpack
122− liftCallCC' = Lift.defaultLiftCallCC' pack unpack
123−
124−-- | Attach a tag to untagged transformers.
125−tagAttach :: proxy t -> DispatchTagAttachT t m a -> m a
126−tagAttach _ = coerce
127−
128−-- | Replace a tag with another tag.
129−tagReplace
130− :: proxy tOld
131− -> proxy tNew
132− -> DispatchTagReplaceT tOld tNew m a
133− -> m a
134−tagReplace _ _ = coerce
135−
136−
137−-- TagAttach instances
138−
139−instance MonadReader tag r m
140− => Class.MonadReader r (DispatchTagAttachT tag m) where
141− ask = let t = Proxy :: Proxy tag in Lift.lift (ask t)
142− local = let t = Proxy :: Proxy tag in Lift.liftLocal (ask t) (local t)
143−
144−instance MonadState tag s m
145− => Class.MonadState s (DispatchTagAttachT tag m) where
146− get = let t = Proxy :: Proxy tag in Lift.lift (get t)
147− put = let t = Proxy :: Proxy tag in Lift.lift . put t
148−
149−instance MonadExcept tag e m
150− => Class.MonadError e (DispatchTagAttachT tag m) where
151− throwError = let t = Proxy :: Proxy tag in Lift.lift . throw t
152− catchError = let t = Proxy :: Proxy tag in Lift.liftCatch (catch t)
153−
154−instance MonadWriter tag w m
155− => Class.MonadWriter w (DispatchTagAttachT tag m) where
156− writer = let t = Proxy :: Proxy tag in Lift.lift . writer t
157− tell = let t = Proxy :: Proxy tag in Lift.lift . tell t
158− listen = let t = Proxy :: Proxy tag in Lift.liftListen (listen t)
159− pass = let t = Proxy :: Proxy tag in Lift.liftPass (pass t)
160−
161−
162−-- TagReplace instances
163−
164−instance MonadReader tNew r m
165− => MonadReader tOld r (DispatchTagReplaceT tOld tNew m) where
166− ask _ = let t = Proxy :: Proxy tNew in Lift.lift (ask t)
167− local _ = let t = Proxy :: Proxy tNew in Lift.liftLocal (ask t) (local t)
168−
169−instance MonadState tNew s m
170− => MonadState tOld s (DispatchTagReplaceT tOld tNew m) where
171− get _ = let t = Proxy :: Proxy tNew in Lift.lift (get t)
172− put _ = let t = Proxy :: Proxy tNew in Lift.lift . put t
173−
174−instance MonadExcept tNew e m
175− => MonadExcept tOld e (DispatchTagReplaceT tOld tNew m) where
176− throw _ = let t = Proxy :: Proxy tNew in Lift.lift . throw t
177− catch _ = let t = Proxy :: Proxy tNew in Lift.liftCatch (catch t)
178−
179−instance MonadWriter tNew w m
180− => MonadWriter tOld w (DispatchTagReplaceT tOld tNew m) where
181− writer _ = let t = Proxy :: Proxy tNew in Lift.lift . writer t
182− tell _ = let t = Proxy :: Proxy tNew in Lift.lift . tell t
183− listen _ = let t = Proxy :: Proxy tNew in Lift.liftListen (listen t)
184− pass _ = let t = Proxy :: Proxy tNew in Lift.liftPass (pass t)
src/Control/Monad/Trans/Ether/Except.hsdeleted−168
@@ -1,168 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE UndecidableInstances #-}
6−{-# LANGUAGE DataKinds #-}
7−{-# LANGUAGE PolyKinds #-}
8−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9−
10−-- | See "Control.Monad.Trans.Except".
11−
12−module Control.Monad.Trans.Ether.Except
13− (
14− -- * The Except monad
15− Except
16− , except
17− , runExcept
18− -- * The ExceptT monad transformer
19− , ExceptT
20− , exceptT
21− , runExceptT
22− -- * Exception operations
23− , throw
24− , catch
25− -- * Newtype operations
26− , pack
27− , unpack
28− ) where
29−
30−import Data.Functor.Identity (Identity(..))
31−import Control.Applicative
32−import Control.Monad (MonadPlus)
33−import Control.Monad.Fix (MonadFix)
34−import Control.Monad.Trans.Class (MonadTrans, lift)
35−import Control.Monad.IO.Class (MonadIO)
36−import Control.Monad.Morph (MFunctor, MMonad)
37−import Control.Monad.Catch (MonadThrow, MonadCatch)
38−import GHC.Generics (Generic)
39−import Data.Coerce (coerce)
40−
41−import qualified Control.Monad.Base as MB
42−import qualified Control.Monad.Trans.Control as MC
43−import qualified Control.Monad.Trans.Except as Trans
44−
45−import qualified Control.Monad.Trans.Lift.StT as Lift
46−import qualified Control.Monad.Trans.Lift.Local as Lift
47−import qualified Control.Monad.Trans.Lift.Catch as Lift
48−import qualified Control.Monad.Trans.Lift.Listen as Lift
49−import qualified Control.Monad.Trans.Lift.Pass as Lift
50−import qualified Control.Monad.Trans.Lift.CallCC as Lift
51−
52−import qualified Control.Monad.Cont.Class as Class
53−import qualified Control.Monad.Reader.Class as Class
54−import qualified Control.Monad.State.Class as Class
55−import qualified Control.Monad.Writer.Class as Class
56−import qualified Control.Monad.Error.Class as Class
57−
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−-- | Runs an 'Except' and returns either an exception or a normal value.
68−runExcept :: proxy tag -> Except tag e a -> Either e a
69−runExcept t = Trans.runExcept . untagged t
70−
71−-- | The exception monad transformer.
72−--
73−-- The 'return' function returns a normal value, while '>>=' exits on
74−-- the first exception.
75−newtype ExceptT tag e m a = ExceptT (Trans.ExceptT e m a)
76− deriving ( Generic
77− , Functor, Applicative, Alternative, Monad, MonadPlus
78− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
79− , MonadThrow, MonadCatch )
80−
81−-- | Type-restricted 'coerce'.
82−pack :: Trans.ExceptT e m a -> ExceptT tag e m a
83−pack = coerce
84−
85−-- | Type-restricted 'coerce'.
86−unpack :: ExceptT tag e m a -> Trans.ExceptT e m a
87−unpack = coerce
88−
89−instance MB.MonadBase b m => MB.MonadBase b (ExceptT tag e m) where
90− liftBase = MB.liftBaseDefault
91−
92−instance MC.MonadTransControl (ExceptT tag e) where
93− type StT (ExceptT tag e) a = MC.StT (Trans.ExceptT e) a
94− liftWith = MC.defaultLiftWith pack unpack
95− restoreT = MC.defaultRestoreT pack
96−
97−instance MC.MonadBaseControl b m => MC.MonadBaseControl b (ExceptT tag e m) where
98− type StM (ExceptT tag e m) a = MC.ComposeSt (ExceptT tag e) m a
99− liftBaseWith = MC.defaultLiftBaseWith
100− restoreM = MC.defaultRestoreM
101−
102−type instance Lift.StT (ExceptT tag e) a = MC.StT (ExceptT tag e) a
103−
104−instance Lift.LiftLocal (ExceptT tag e) where
105− liftLocal = Lift.defaultLiftLocal pack unpack
106−
107−instance Lift.LiftCatch (ExceptT tag e) where
108− liftCatch = Lift.defaultLiftCatch pack unpack
109−
110−instance Lift.LiftListen (ExceptT tag e) where
111− liftListen = Lift.defaultLiftListen pack unpack
112−
113−instance Lift.LiftPass (ExceptT tag e) where
114− liftPass = Lift.defaultLiftPass pack unpack
115−
116−instance Lift.LiftCallCC (ExceptT tag e) where
117− liftCallCC = Lift.defaultLiftCallCC pack unpack
118− liftCallCC' = Lift.defaultLiftCallCC pack unpack
119−
120−tagged :: proxy tag -> Trans.ExceptT e m a -> ExceptT tag e m a
121−tagged _ = pack
122−
123−untagged :: proxy tag -> ExceptT tag e m a -> Trans.ExceptT e m a
124−untagged _ = unpack
125−
126−-- | Constructor for computations in the exception monad transformer.
127−exceptT :: proxy tag -> m (Either e a) -> ExceptT tag e m a
128−exceptT t = tagged t . Trans.ExceptT
129−
130−-- | Constructor for computations in the exception monad
131−-- (the inverse of 'runExcept').
132−except :: Monad m => proxy tag -> Either e a -> ExceptT tag e m a
133−except t = exceptT t . return
134−
135−-- | Runs an 'ExceptT' and returns either an exception or a normal value.
136−runExceptT :: proxy tag -> ExceptT tag e m a -> m (Either e a)
137−runExceptT t = Trans.runExceptT . untagged t
138−
139−-- | Is used within a monadic computation to begin exception processing.
140−throw :: Monad m => proxy tag -> e -> ExceptT tag e m a
141−throw t = tagged t . Trans.throwE
142−
143−-- | A handler function to handle previous exceptions and return to normal execution.
144−catch :: Monad m => proxy tag -> ExceptT tag e m a -> (e -> ExceptT tag e m a) -> ExceptT tag e m a
145−catch t m h = tagged t $ Trans.catchE (untagged t m) (untagged t . h)
146−
147−instance Class.MonadCont m => Class.MonadCont (ExceptT tag e m) where
148− callCC = Lift.liftCallCC Class.callCC
149−
150−instance Class.MonadReader r m => Class.MonadReader r (ExceptT tag e m) where
151− ask = lift Class.ask
152− local = Lift.liftLocal Class.ask Class.local
153− reader = lift . Class.reader
154−
155−instance Class.MonadState s m => Class.MonadState s (ExceptT tag e m) where
156− get = lift Class.get
157− put = lift . Class.put
158− state = lift . Class.state
159−
160−instance Class.MonadWriter w m => Class.MonadWriter w (ExceptT tag e m) where
161− writer = lift . Class.writer
162− tell = lift . Class.tell
163− listen = Lift.liftListen Class.listen
164− pass = Lift.liftPass Class.pass
165−
166−instance Class.MonadError e' m => Class.MonadError e' (ExceptT tag e m) where
167− throwError = lift . Class.throwError
168− catchError = Lift.liftCatch Class.catchError
src/Control/Monad/Trans/Ether/Reader.hsdeleted−181
@@ -1,181 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE UndecidableInstances #-}
6−{-# LANGUAGE DataKinds #-}
7−{-# LANGUAGE PolyKinds #-}
8−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9−
10−-- | See "Control.Monad.Trans.Reader".
11−
12−module Control.Monad.Trans.Ether.Reader
13− (
14− -- * The Reader monad
15− Reader
16− , reader
17− , runReader
18− -- * The ReaderT monad transformer
19− , ReaderT
20− , readerT
21− , runReaderT
22− -- * Reader operations
23− , ask
24− , local
25− -- * Newtype operations
26− , pack
27− , unpack
28− ) where
29−
30−import Data.Functor.Identity (Identity(..))
31−import Control.Applicative
32−import Control.Monad (MonadPlus)
33−import Control.Monad.Fix (MonadFix)
34−import Control.Monad.Trans.Class (MonadTrans, lift)
35−import Control.Monad.IO.Class (MonadIO)
36−import Control.Monad.Morph (MFunctor, MMonad)
37−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
38−import GHC.Generics (Generic)
39−import Data.Coerce (coerce)
40−
41−import qualified Control.Monad.Base as MB
42−import qualified Control.Monad.Trans.Control as MC
43−import qualified Control.Monad.Trans.Reader as Trans
44−
45−import qualified Control.Monad.Trans.Lift.StT as Lift
46−import qualified Control.Monad.Trans.Lift.Local as Lift
47−import qualified Control.Monad.Trans.Lift.Catch as Lift
48−import qualified Control.Monad.Trans.Lift.Listen as Lift
49−import qualified Control.Monad.Trans.Lift.Pass as Lift
50−import qualified Control.Monad.Trans.Lift.CallCC as Lift
51−
52−import qualified Control.Monad.Cont.Class as Class
53−import qualified Control.Monad.Reader.Class as Class
54−import qualified Control.Monad.State.Class as Class
55−import qualified Control.Monad.Writer.Class as Class
56−import qualified Control.Monad.Error.Class as Class
57−
58−-- | The parameterizable reader monad.
59−--
60−-- Computations are functions of a shared environment.
61−--
62−-- The 'return' function ignores the environment, while '>>=' passes
63−-- the inherited environment to both subcomputations.
64−type Reader tag r = ReaderT tag r Identity
65−
66−-- | The reader monad transformer,
67−-- which adds a read-only environment to the given monad.
68−--
69−-- The 'return' function ignores the environment, while '>>=' passes
70−-- the inherited environment to both subcomputations.
71−newtype ReaderT tag r m a = ReaderT (Trans.ReaderT r m a)
72− deriving ( Generic
73− , Functor, Applicative, Alternative, Monad, MonadPlus
74− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
75− , MonadThrow, MonadCatch, MonadMask )
76−
77−-- | Type-restricted 'coerce'.
78−pack :: Trans.ReaderT r m a -> ReaderT tag r m a
79−pack = coerce
80−
81−-- | Type-restricted 'coerce'.
82−unpack :: ReaderT tag r m a -> Trans.ReaderT r m a
83−unpack = coerce
84−
85−instance MB.MonadBase b m => MB.MonadBase b (ReaderT tag r m) where
86− liftBase = MB.liftBaseDefault
87−
88−instance MC.MonadTransControl (ReaderT tag r) where
89− type StT (ReaderT tag r) a = MC.StT (Trans.ReaderT r) a
90− liftWith = MC.defaultLiftWith pack unpack
91− restoreT = MC.defaultRestoreT pack
92−
93−instance MC.MonadBaseControl b m => MC.MonadBaseControl b (ReaderT tag r m) where
94− type StM (ReaderT tag r m) a = MC.ComposeSt (ReaderT tag r) m a
95− liftBaseWith = MC.defaultLiftBaseWith
96− restoreM = MC.defaultRestoreM
97−
98−type instance Lift.StT (ReaderT tag r) a = MC.StT (ReaderT tag r) a
99−
100−instance Lift.LiftLocal (ReaderT tag r) where
101− liftLocal = Lift.defaultLiftLocal pack unpack
102−
103−instance Lift.LiftCatch (ReaderT tag r) where
104− liftCatch = Lift.defaultLiftCatch pack unpack
105−
106−instance Lift.LiftListen (ReaderT tag r) where
107− liftListen = Lift.defaultLiftListen pack unpack
108−
109−instance Lift.LiftPass (ReaderT tag r) where
110− liftPass = Lift.defaultLiftPass pack unpack
111−
112−instance Lift.LiftCallCC (ReaderT tag r) where
113− liftCallCC = Lift.defaultLiftCallCC pack unpack
114− liftCallCC' = Lift.defaultLiftCallCC' pack unpack
115−
116−tagged :: proxy tag -> Trans.ReaderT r m a -> ReaderT tag r m a
117−tagged _ = pack
118−
119−untagged :: proxy tag -> ReaderT tag r m a -> Trans.ReaderT r m a
120−untagged _ = unpack
121−
122−-- | Constructor for computations in the reader monad transformer.
123−readerT :: proxy tag -> (r -> m a) -> ReaderT tag r m a
124−readerT t = tagged t . Trans.ReaderT
125−
126−-- | Constructor for computations in the reader monad
127−-- (the inverse of 'runReader').
128−reader :: Monad m => proxy tag -> (r -> a) -> ReaderT tag r m a
129−reader t = tagged t . Trans.reader
130−
131−-- | Runs a 'ReaderT' with the given environment
132−-- and returns the vinal value.
133−runReaderT :: proxy tag -> ReaderT tag r m a -> r -> m a
134−runReaderT t = Trans.runReaderT . untagged t
135−
136−-- | Runs a 'ReaderT' with the given environment
137−-- and returns the vinal value.
138−runReader :: proxy tag -> Reader tag r a -> r -> a
139−runReader t = Trans.runReader . untagged t
140−
141−-- | Fetch the value of the environment.
142−ask :: Monad m => proxy tag -> ReaderT tag r m r
143−ask t = tagged t Trans.ask
144−
145−-- | Execute a computation in a modified environment
146−-- (a specialization of 'withReaderT').
147−--
148−-- * @'runReaderT' tag ('local' tag f m) = 'runReaderT' tag m . f@
149−local
150− :: proxy tag
151− -> (r -> r)
152− -- ^ The function to modify the environment.
153− -> ReaderT tag r m a
154− -- ^ Computation to run in the modified environment.
155− -> ReaderT tag r m a
156−local t f m = tagged t $ Trans.withReaderT f (untagged t m)
157−
158−-- Instances for mtl classes
159−
160−instance Class.MonadCont m => Class.MonadCont (ReaderT tag r m) where
161− callCC = Lift.liftCallCC Class.callCC
162−
163−instance Class.MonadReader r' m => Class.MonadReader r' (ReaderT tag r m) where
164− ask = lift Class.ask
165− local = Lift.liftLocal Class.ask Class.local
166− reader = lift . Class.reader
167−
168−instance Class.MonadState s m => Class.MonadState s (ReaderT tag r m) where
169− get = lift Class.get
170− put = lift . Class.put
171− state = lift . Class.state
172−
173−instance Class.MonadWriter w m => Class.MonadWriter w (ReaderT tag r m) 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 Class.MonadError e m => Class.MonadError e (ReaderT tag r m) where
180− throwError = lift . Class.throwError
181− catchError = Lift.liftCatch Class.catchError
src/Control/Monad/Trans/Ether/State.hsdeleted−8
@@ -1,8 +0,0 @@
1−
2−-- | See "Control.Monad.Trans.State".
3−
4−module Control.Monad.Trans.Ether.State
5− ( module Control.Monad.Trans.Ether.State.Lazy
6− ) where
7−
8−import Control.Monad.Trans.Ether.State.Lazy
src/Control/Monad/Trans/Ether/State/Lazy.hsdeleted−196
@@ -1,196 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE UndecidableInstances #-}
6−{-# LANGUAGE DataKinds #-}
7−{-# LANGUAGE PolyKinds #-}
8−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9−
10−-- | See "Control.Monad.Trans.State.Lazy".
11−
12−module Control.Monad.Trans.Ether.State.Lazy
13− (
14− -- * The State monad
15− State
16− , state
17− , runState
18− , evalState
19− , execState
20− -- * The StateT monad transformer
21− , StateT
22− , stateT
23− , runStateT
24− , evalStateT
25− , execStateT
26− -- * State operations
27− , get
28− , put
29− -- * Newtype operations
30− , pack
31− , unpack
32− ) where
33−
34−import Data.Functor.Identity (Identity(..))
35−import Control.Applicative
36−import Control.Monad (MonadPlus)
37−import Control.Monad.Fix (MonadFix)
38−import Control.Monad.Trans.Class (MonadTrans, lift)
39−import Control.Monad.IO.Class (MonadIO)
40−import Control.Monad.Morph (MFunctor)
41−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
42−import GHC.Generics (Generic)
43−import Data.Coerce (coerce)
44−
45−import qualified Control.Monad.Base as MB
46−import qualified Control.Monad.Trans.Control as MC
47−import qualified Control.Monad.Trans.State.Lazy as Trans
48−
49−import qualified Control.Monad.Trans.Lift.StT as Lift
50−import qualified Control.Monad.Trans.Lift.Local as Lift
51−import qualified Control.Monad.Trans.Lift.Catch as Lift
52−import qualified Control.Monad.Trans.Lift.Listen as Lift
53−import qualified Control.Monad.Trans.Lift.Pass as Lift
54−import qualified Control.Monad.Trans.Lift.CallCC as Lift
55−
56−import qualified Control.Monad.Cont.Class as Class
57−import qualified Control.Monad.Reader.Class as Class
58−import qualified Control.Monad.State.Class as Class
59−import qualified Control.Monad.Writer.Class as Class
60−import qualified Control.Monad.Error.Class as Class
61−
62−
63−-- | The parametrizable state monad.
64−--
65−-- Computations have access to a mutable state.
66−--
67−-- The 'return' function leaves the state unchanged, while '>>=' uses
68−-- the final state of the first computation as the initial state of the second.
69−type State tag r = StateT tag r Identity
70−
71−-- | The state monad transformer.
72−--
73−-- The 'return' function leaves the state unchanged, while '>>=' uses
74−-- the final state of the first computation as the initial state of the second.
75−newtype StateT tag s m a = StateT (Trans.StateT s m a)
76− deriving ( Generic
77− , Functor, Applicative, Alternative, Monad, MonadPlus
78− , MonadFix, MonadTrans, MonadIO, MFunctor
79− , MonadThrow, MonadCatch, MonadMask )
80−
81−-- | Type-restricted 'coerce'.
82−pack :: Trans.StateT s m a -> StateT tag s m a
83−pack = coerce
84−
85−-- | Type-restricted 'coerce'.
86−unpack :: StateT tag s m a -> Trans.StateT s m a
87−unpack = coerce
88−
89−instance MB.MonadBase b m => MB.MonadBase b (StateT tag s m) where
90− liftBase = MB.liftBaseDefault
91−
92−instance MC.MonadTransControl (StateT tag s) where
93− type StT (StateT tag s) a = MC.StT (Trans.StateT s) a
94− liftWith = MC.defaultLiftWith pack unpack
95− restoreT = MC.defaultRestoreT pack
96−
97−instance MC.MonadBaseControl b m => MC.MonadBaseControl b (StateT tag s m) where
98− type StM (StateT tag s m) a = MC.ComposeSt (StateT tag s) m a
99− liftBaseWith = MC.defaultLiftBaseWith
100− restoreM = MC.defaultRestoreM
101−
102−type instance Lift.StT (StateT tag s) a = MC.StT (StateT tag s) a
103−
104−instance Lift.LiftLocal (StateT tag s) where
105− liftLocal = Lift.defaultLiftLocal pack unpack
106−
107−instance Lift.LiftCatch (StateT tag s) where
108− liftCatch = Lift.defaultLiftCatch pack unpack
109−
110−instance Lift.LiftListen (StateT tag s) where
111− liftListen = Lift.defaultLiftListen pack unpack
112−
113−instance Lift.LiftPass (StateT tag s) where
114− liftPass = Lift.defaultLiftPass pack unpack
115−
116−instance Lift.LiftCallCC (StateT tag s) where
117− liftCallCC = Lift.defaultLiftCallCC pack unpack
118− liftCallCC' = Lift.defaultLiftCallCC' pack unpack
119−
120−tagged :: proxy tag -> Trans.StateT s m a -> StateT tag s m a
121−tagged _ = pack
122−
123−untagged :: proxy tag -> StateT tag s m a -> Trans.StateT s m a
124−untagged _ = unpack
125−
126−-- | Constructor for computations in the state monad transformer.
127−stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
128−stateT t = tagged t . Trans.StateT
129−
130−-- | Constructor for computations in the state monad
131−-- (the inverse of 'runState').
132−state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
133−state t = tagged t . Trans.state
134−
135−-- | Runs a 'StateT' with the given initial state
136−-- and returns both the final value and the final state.
137−runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
138−runStateT t = Trans.runStateT . untagged t
139−
140−-- | Runs a 'StateT' with the given initial state
141−-- and returns the final value, discarding the final state.
142−evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
143−evalStateT t = Trans.evalStateT . untagged t
144−
145−-- | Runs a 'StateT' with the given initial state
146−-- and returns the final state, discarding the final value.
147−execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
148−execStateT t = Trans.execStateT . untagged t
149−
150−-- | Runs a 'State' with the given initial state
151−-- and returns both the final value and the final state.
152−runState :: proxy tag -> State tag s a -> s -> (a, s)
153−runState t = Trans.runState . untagged t
154−
155−-- | Runs a 'State' with the given initial state
156−-- and returns the final value, discarding the final state.
157−evalState :: proxy tag -> State tag s a -> s -> a
158−evalState t = Trans.evalState . untagged t
159−
160−-- | Runs a 'State' with the given initial state
161−-- and returns the final state, discarding the final value.
162−execState :: proxy tag -> State tag s a -> s -> s
163−execState t = Trans.execState . untagged t
164−
165−-- | Fetch the current value of the state within the monad.
166−get :: Monad m => proxy tag -> StateT tag s m s
167−get t = tagged t Trans.get
168−
169−-- | Set the value of the state within the monad.
170−put :: Monad m => proxy tag -> s -> StateT tag s m ()
171−put t = tagged t . Trans.put
172−
173−-- Instances for mtl classes
174−
175−instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
176− callCC = Lift.liftCallCC' Class.callCC
177−
178−instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
179− ask = lift Class.ask
180− local = Lift.liftLocal Class.ask Class.local
181− reader = lift . Class.reader
182−
183−instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
184− get = lift Class.get
185− put = lift . Class.put
186− state = lift . Class.state
187−
188−instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
189− writer = lift . Class.writer
190− tell = lift . Class.tell
191− listen = Lift.liftListen Class.listen
192− pass = Lift.liftPass Class.pass
193−
194−instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
195− throwError = lift . Class.throwError
196− catchError = Lift.liftCatch Class.catchError
src/Control/Monad/Trans/Ether/State/Strict.hsdeleted−196
@@ -1,196 +0,0 @@
1−{-# LANGUAGE DeriveGeneric #-}
2−{-# LANGUAGE MultiParamTypeClasses #-}
3−{-# LANGUAGE TypeFamilies #-}
4−{-# LANGUAGE FlexibleInstances #-}
5−{-# LANGUAGE UndecidableInstances #-}
6−{-# LANGUAGE DataKinds #-}
7−{-# LANGUAGE PolyKinds #-}
8−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
9−
10−-- | See "Control.Monad.Trans.State.Strict".
11−
12−module Control.Monad.Trans.Ether.State.Strict
13− (
14− -- * The State monad
15− State
16− , state
17− , runState
18− , evalState
19− , execState
20− -- * The StateT monad transformer
21− , StateT
22− , stateT
23− , runStateT
24− , evalStateT
25− , execStateT
26− -- * State operations
27− , get
28− , put
29− -- * Newtype operations
30− , pack
31− , unpack
32− ) where
33−
34−import Data.Functor.Identity (Identity(..))
35−import Control.Applicative
36−import Control.Monad (MonadPlus)
37−import Control.Monad.Fix (MonadFix)
38−import Control.Monad.Trans.Class (MonadTrans, lift)
39−import Control.Monad.IO.Class (MonadIO)
40−import Control.Monad.Morph (MFunctor)
41−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
42−import GHC.Generics (Generic)
43−import Data.Coerce (coerce)
44−
45−import qualified Control.Monad.Base as MB
46−import qualified Control.Monad.Trans.Control as MC
47−import qualified Control.Monad.Trans.State.Strict as Trans
48−
49−import qualified Control.Monad.Trans.Lift.StT as Lift
50−import qualified Control.Monad.Trans.Lift.Local as Lift
51−import qualified Control.Monad.Trans.Lift.Catch as Lift
52−import qualified Control.Monad.Trans.Lift.Listen as Lift
53−import qualified Control.Monad.Trans.Lift.Pass as Lift
54−import qualified Control.Monad.Trans.Lift.CallCC as Lift
55−
56−import qualified Control.Monad.Cont.Class as Class
57−import qualified Control.Monad.Reader.Class as Class
58−import qualified Control.Monad.State.Class as Class
59−import qualified Control.Monad.Writer.Class as Class
60−import qualified Control.Monad.Error.Class as Class
61−
62−
63−-- | The parametrizable state monad.
64−--
65−-- Computations have access to a mutable state.
66−--
67−-- The 'return' function leaves the state unchanged, while '>>=' uses
68−-- the final state of the first computation as the initial state of the second.
69−type State tag r = StateT tag r Identity
70−
71−-- | The state monad transformer.
72−--
73−-- The 'return' function leaves the state unchanged, while '>>=' uses
74−-- the final state of the first computation as the initial state of the second.
75−newtype StateT tag s m a = StateT (Trans.StateT s m a)
76− deriving ( Generic
77− , Functor, Applicative, Alternative, Monad, MonadPlus
78− , MonadFix, MonadTrans, MonadIO, MFunctor
79− , MonadThrow, MonadCatch, MonadMask )
80−
81−-- | Type-restricted 'coerce'.
82−pack :: Trans.StateT s m a -> StateT tag s m a
83−pack = coerce
84−
85−-- | Type-restricted 'coerce'.
86−unpack :: StateT tag s m a -> Trans.StateT s m a
87−unpack = coerce
88−
89−instance MB.MonadBase b m => MB.MonadBase b (StateT tag s m) where
90− liftBase = MB.liftBaseDefault
91−
92−instance MC.MonadTransControl (StateT tag s) where
93− type StT (StateT tag s) a = MC.StT (Trans.StateT s) a
94− liftWith = MC.defaultLiftWith pack unpack
95− restoreT = MC.defaultRestoreT pack
96−
97−instance MC.MonadBaseControl b m => MC.MonadBaseControl b (StateT tag s m) where
98− type StM (StateT tag s m) a = MC.ComposeSt (StateT tag s) m a
99− liftBaseWith = MC.defaultLiftBaseWith
100− restoreM = MC.defaultRestoreM
101−
102−type instance Lift.StT (StateT tag s) a = MC.StT (StateT tag s) a
103−
104−instance Lift.LiftLocal (StateT tag s) where
105− liftLocal = Lift.defaultLiftLocal pack unpack
106−
107−instance Lift.LiftCatch (StateT tag s) where
108− liftCatch = Lift.defaultLiftCatch pack unpack
109−
110−instance Lift.LiftListen (StateT tag s) where
111− liftListen = Lift.defaultLiftListen pack unpack
112−
113−instance Lift.LiftPass (StateT tag s) where
114− liftPass = Lift.defaultLiftPass pack unpack
115−
116−instance Lift.LiftCallCC (StateT tag s) where
117− liftCallCC = Lift.defaultLiftCallCC pack unpack
118− liftCallCC' = Lift.defaultLiftCallCC' pack unpack
119−
120−tagged :: proxy tag -> Trans.StateT s m a -> StateT tag s m a
121−tagged _ = pack
122−
123−untagged :: proxy tag -> StateT tag s m a -> Trans.StateT s m a
124−untagged _ = unpack
125−
126−-- | Constructor for computations in the state monad transformer.
127−stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
128−stateT t = tagged t . Trans.StateT
129−
130−-- | Constructor for computations in the state monad
131−-- (the inverse of 'runState').
132−state :: Monad m => proxy tag -> (s -> (a, s)) -> StateT tag s m a
133−state t = tagged t . Trans.state
134−
135−-- | Runs a 'StateT' with the given initial state
136−-- and returns both the final value and the final state.
137−runStateT :: proxy tag -> StateT tag s m a -> s -> m (a, s)
138−runStateT t = Trans.runStateT . untagged t
139−
140−-- | Runs a 'StateT' with the given initial state
141−-- and returns the final value, discarding the final state.
142−evalStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m a
143−evalStateT t = Trans.evalStateT . untagged t
144−
145−-- | Runs a 'StateT' with the given initial state
146−-- and returns the final state, discarding the final value.
147−execStateT :: Monad m => proxy tag -> StateT tag s m a -> s -> m s
148−execStateT t = Trans.execStateT . untagged t
149−
150−-- | Runs a 'State' with the given initial state
151−-- and returns both the final value and the final state.
152−runState :: proxy tag -> State tag s a -> s -> (a, s)
153−runState t = Trans.runState . untagged t
154−
155−-- | Runs a 'State' with the given initial state
156−-- and returns the final value, discarding the final state.
157−evalState :: proxy tag -> State tag s a -> s -> a
158−evalState t = Trans.evalState . untagged t
159−
160−-- | Runs a 'State' with the given initial state
161−-- and returns the final state, discarding the final value.
162−execState :: proxy tag -> State tag s a -> s -> s
163−execState t = Trans.execState . untagged t
164−
165−-- | Fetch the current value of the state within the monad.
166−get :: Monad m => proxy tag -> StateT tag s m s
167−get t = tagged t Trans.get
168−
169−-- | Set the value of the state within the monad.
170−put :: Monad m => proxy tag -> s -> StateT tag s m ()
171−put t = tagged t . Trans.put
172−
173−-- Instances for mtl classes
174−
175−instance Class.MonadCont m => Class.MonadCont (StateT tag s m) where
176− callCC = Lift.liftCallCC' Class.callCC
177−
178−instance Class.MonadReader r m => Class.MonadReader r (StateT tag s m) where
179− ask = lift Class.ask
180− local = Lift.liftLocal Class.ask Class.local
181− reader = lift . Class.reader
182−
183−instance Class.MonadState s' m => Class.MonadState s' (StateT tag s m) where
184− get = lift Class.get
185− put = lift . Class.put
186− state = lift . Class.state
187−
188−instance Class.MonadWriter w m => Class.MonadWriter w (StateT tag s m) where
189− writer = lift . Class.writer
190− tell = lift . Class.tell
191− listen = Lift.liftListen Class.listen
192− pass = Lift.liftPass Class.pass
193−
194−instance Class.MonadError e m => Class.MonadError e (StateT tag s m) where
195− throwError = lift . Class.throwError
196− catchError = Lift.liftCatch Class.catchError
src/Control/Monad/Trans/Ether/Writer.hsdeleted−192
@@ -1,192 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−{-# LANGUAGE DeriveGeneric #-}
3−{-# LANGUAGE MultiParamTypeClasses #-}
4−{-# LANGUAGE TypeFamilies #-}
5−{-# LANGUAGE FlexibleInstances #-}
6−{-# LANGUAGE UndecidableInstances #-}
7−{-# LANGUAGE DataKinds #-}
8−{-# LANGUAGE PolyKinds #-}
9−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10−
11−-- | See "Control.Monad.Trans.Writer".
12−
13−module Control.Monad.Trans.Ether.Writer
14− (
15− -- * The Writer monad
16− Writer
17− , writer
18− , runWriter
19− , execWriter
20− -- * The WriterT monad transformer
21− , WriterT
22− , writerT
23− , runWriterT
24− , execWriterT
25− -- * Writer operations
26− , tell
27− , listen
28− , pass
29− -- * Newtype operations
30− , pack
31− , unpack
32− ) where
33−
34−#if __GLASGOW_HASKELL__ < 710
35−import Data.Monoid
36−#endif
37−
38−import Data.Functor.Identity (Identity(..))
39−import Control.Applicative
40−import Control.Monad (MonadPlus)
41−import Control.Monad.Fix (MonadFix)
42−import Control.Monad.Trans.Class (MonadTrans, lift)
43−import Control.Monad.IO.Class (MonadIO)
44−import Control.Monad.Morph (MFunctor, MMonad)
45−import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
46−import GHC.Generics (Generic)
47−import Data.Coerce (coerce)
48−
49−import qualified Control.Monad.Base as MB
50−import qualified Control.Monad.Trans.Control as MC
51−import qualified Control.Monad.Trans.Writer.Lazy as Trans
52−
53−import qualified Control.Monad.Trans.Lift.StT as Lift
54−import qualified Control.Monad.Trans.Lift.Local as Lift
55−import qualified Control.Monad.Trans.Lift.Catch as Lift
56−import qualified Control.Monad.Trans.Lift.Listen as Lift
57−import qualified Control.Monad.Trans.Lift.Pass as Lift
58−import qualified Control.Monad.Trans.Lift.CallCC as Lift
59−
60−import qualified Control.Monad.Cont.Class as Class
61−import qualified Control.Monad.Reader.Class as Class
62−import qualified Control.Monad.State.Class as Class
63−import qualified Control.Monad.Writer.Class as Class
64−import qualified Control.Monad.Error.Class as Class
65−
66−-- | The parametrizable writer monad.
67−--
68−-- Computations can accumulate a monoid value.
69−--
70−-- The 'return' function produces the output 'mempty', while '>>=' combines
71−-- the outputs of the subcomputations using 'mappend'.
72−type Writer tag w = WriterT tag w Identity
73−
74−-- | The writer monad transformer.
75−--
76−-- The 'return' function produces the output 'mempty', while '>>=' combines
77−-- the outputs of the subcomputations using 'mappend'.
78−newtype WriterT tag w m a = WriterT (Trans.WriterT w m a)
79− deriving ( Generic
80− , Functor, Applicative, Alternative, Monad, MonadPlus
81− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
82− , MonadThrow, MonadCatch, MonadMask )
83−
84−-- | Type-restricted 'coerce'.
85−pack :: Trans.WriterT w m a -> WriterT tag w m a
86−pack = coerce
87−
88−-- | Type-restricted 'coerce'.
89−unpack :: WriterT tag w m a -> Trans.WriterT w m a
90−unpack = coerce
91−
92−instance (Monoid w, MB.MonadBase b m) => MB.MonadBase b (WriterT tag w m) where
93− liftBase = MB.liftBaseDefault
94−
95−instance Monoid w => MC.MonadTransControl (WriterT tag w) where
96− type StT (WriterT tag w) a = MC.StT (Trans.WriterT w) a
97− liftWith = MC.defaultLiftWith pack unpack
98− restoreT = MC.defaultRestoreT pack
99−
100−instance (Monoid w, MC.MonadBaseControl b m) => MC.MonadBaseControl b (WriterT tag w m) where
101− type StM (WriterT tag w m) a = MC.ComposeSt (WriterT tag w) m a
102− liftBaseWith = MC.defaultLiftBaseWith
103− restoreM = MC.defaultRestoreM
104−
105−type instance Lift.StT (WriterT tag w) a = MC.StT (WriterT tag w) a
106−
107−instance Monoid w => Lift.LiftLocal (WriterT tag w) where
108− liftLocal = Lift.defaultLiftLocal pack unpack
109−
110−instance Monoid w => Lift.LiftCatch (WriterT tag w) where
111− liftCatch = Lift.defaultLiftCatch pack unpack
112−
113−instance Monoid w => Lift.LiftListen (WriterT tag w) where
114− liftListen = Lift.defaultLiftListen pack unpack
115−
116−instance Monoid w' => Lift.LiftPass (WriterT tag w') where
117− liftPass = Lift.defaultLiftPass pack unpack
118−
119−instance Monoid w => Lift.LiftCallCC (WriterT tag w) where
120− liftCallCC = Lift.defaultLiftCallCC pack unpack
121− liftCallCC' = Lift.defaultLiftCallCC pack unpack
122−
123−tagged :: proxy tag -> Trans.WriterT w m a -> WriterT tag w m a
124−tagged _ = pack
125−
126−untagged :: proxy tag -> WriterT tag w m a -> Trans.WriterT w m a
127−untagged _ = unpack
128−
129−-- | Constructor for computations in the writer monad transformer.
130−writerT :: proxy tag -> m (a, w) -> WriterT tag w m a
131−writerT t = tagged t . Trans.WriterT
132−
133−-- | Constructor for computations in the writer monad
134−-- (the inverse of 'runWriter').
135−writer :: Monad m => proxy tag -> (a, w) -> WriterT tag w m a
136−writer t = tagged t . Trans.writer
137−
138−-- | Runs a 'WriterT' and returns both the normal value
139−-- and the final accumulator.
140−runWriterT :: proxy tag -> WriterT tag w m a -> m (a, w)
141−runWriterT t = Trans.runWriterT . untagged t
142−
143−-- | Runs a 'Writer' and returns both the normal value
144−-- and the final accumulator.
145−runWriter :: proxy tag -> Writer tag w a -> (a, w)
146−runWriter t = Trans.runWriter . untagged t
147−
148−-- | Runs a 'WriterT' and returns the final accumulator,
149−-- discarding the normal value.
150−execWriterT :: Monad m => proxy tag -> WriterT tag w m a -> m w
151−execWriterT t = Trans.execWriterT . untagged t
152−
153−-- | Runs a 'Writer' and returns the final accumulator,
154−-- discarding the normal value.
155−execWriter :: proxy tag -> Writer tag w a -> w
156−execWriter t = Trans.execWriter . untagged t
157−
158−-- | Appends a value to the accumulator within the monad.
159−tell :: Monad m => proxy tag -> w -> WriterT tag w m ()
160−tell t w = writer t ((), w)
161−
162−-- | Executes an action and adds its accumulator to the value of the computation.
163−listen :: (Monoid w, Monad m) => proxy tag -> WriterT tag w m a -> WriterT tag w m (a, w)
164−listen t m = tagged t $ Trans.listen (untagged t m)
165−
166−-- | Executes an action which returns a value and a function, and returns the
167−-- value, applying the function to the accumulator.
168−pass :: (Monoid w, Monad m) => proxy tag -> WriterT tag w m (a, w -> w) -> WriterT tag w m a
169−pass t m = tagged t $ Trans.pass (untagged t m)
170−
171−instance (Monoid w, Class.MonadCont m) => Class.MonadCont (WriterT tag w m) where
172− callCC = Lift.liftCallCC Class.callCC
173−
174−instance (Monoid w, Class.MonadReader r m) => Class.MonadReader r (WriterT tag w m) where
175− ask = lift Class.ask
176− local = Lift.liftLocal Class.ask Class.local
177− reader = lift . Class.reader
178−
179−instance (Monoid w, Class.MonadState s m) => Class.MonadState s (WriterT tag w m) where
180− get = lift Class.get
181− put = lift . Class.put
182− state = lift . Class.state
183−
184−instance (Monoid w, Class.MonadWriter w' m) => Class.MonadWriter w' (WriterT tag w m) where
185− writer = lift . Class.writer
186− tell = lift . Class.tell
187− listen = Lift.liftListen Class.listen
188− pass = Lift.liftPass Class.pass
189−
190−instance (Monoid w, Class.MonadError e m) => Class.MonadError e (WriterT tag w m) where
191− throwError = lift . Class.throwError
192− catchError = Lift.liftCatch Class.catchError
src/Ether.hsnew file+25
@@ -0,0 +1,25 @@
1+module Ether
2+ ( module Control.Monad
3+ , module Control.Monad.Fix
4+ , module Control.Monad.Trans.Identity
5+ , module Data.Functor.Identity
6+ , module Data.Tagged
7+ , module Ether.Reader
8+ , module Ether.Writer
9+ , module Ether.State
10+ , module Ether.Except
11+ , module Ether.TagDispatch
12+ , module Ether.TaggedTrans
13+ ) where
14+
15+import Control.Monad
16+import Control.Monad.Fix
17+import Control.Monad.Trans.Identity
18+import Data.Functor.Identity
19+import Data.Tagged
20+import Ether.Reader
21+import Ether.Writer
22+import Ether.State
23+import Ether.Except
24+import Ether.TagDispatch
25+import Ether.TaggedTrans
src/Ether/Except.hsnew file+127
@@ -0,0 +1,127 @@
1+module Ether.Except
2+ (
3+ -- * MonadExcept class
4+ MonadExcept
5+ , throw
6+ , catch
7+ -- * The Except monad
8+ , Except
9+ , runExcept
10+ -- * The ExceptT monad transformer
11+ , ExceptT
12+ , exceptT
13+ , runExceptT
14+ -- * MonadExcept class (implicit)
15+ , MonadExcept'
16+ , throw'
17+ , catch'
18+ -- * The Except monad (implicit)
19+ , Except'
20+ , runExcept'
21+ -- * The ExceptT monad transformer (implicit)
22+ , ExceptT'
23+ , exceptT'
24+ , runExceptT'
25+ -- * Internal labels
26+ , TAGGED
27+ , EXCEPT
28+ ) where
29+
30+import qualified Control.Monad.Except as T
31+import Control.Monad.Signatures (Catch)
32+import qualified Control.Monad.Trans.Lift.Catch as Lift
33+import Data.Coerce
34+import Data.Functor.Identity
35+
36+import Ether.TaggedTrans
37+import Ether.Internal
38+
39+class Monad m => MonadExcept tag e m | m tag -> e where
40+
41+ -- | Is used within a monadic computation to begin exception processing.
42+ throw :: e -> m a
43+
44+ -- | A TaggedTrans function to handle previous exceptions and return to
45+ -- normal execution.
46+ catch :: m a -> (e -> m a) -> m a
47+
48+instance {-# OVERLAPPABLE #-}
49+ ( Lift.LiftCatch t
50+ , Monad (t m)
51+ , MonadExcept tag e m
52+ ) => MonadExcept tag e (t m) where
53+ throw = Lift.lift . throw @tag
54+ catch = Lift.liftCatch (catch @tag)
55+
56+-- | Encode type-level information for 'ExceptT'.
57+data EXCEPT
58+
59+-- | The parameterizable exception monad.
60+--
61+-- Computations are either exceptions or normal values.
62+--
63+-- The 'return' function returns a normal value, while '>>=' exits on
64+-- the first exception.
65+type Except tag e = ExceptT tag e Identity
66+
67+-- | The exception monad transformer.
68+--
69+-- The 'return' function returns a normal value, while '>>=' exits on
70+-- the first exception.
71+type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
72+
73+-- | Runs an 'Except' and returns either an exception or a normal value.
74+runExcept :: forall tag e a . Except tag e a -> Either e a
75+runExcept = coerce (T.runExcept @e @a)
76+
77+-- | Runs an 'ExceptT' and returns either an exception or a normal value.
78+runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
79+runExceptT = coerce (T.runExceptT @e @m @a)
80+
81+-- | Constructor for computations in the exception monad transformer.
82+exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
83+exceptT = coerce (T.ExceptT @e @m @a)
84+
85+type instance HandleSuper EXCEPT e trans = ()
86+type instance HandleConstraint EXCEPT e trans m =
87+ T.MonadError e (trans m)
88+
89+instance Handle EXCEPT e (T.ExceptT e) where
90+ handling r = r
91+
92+instance
93+ ( Handle EXCEPT e trans
94+ , Monad m, Monad (trans m)
95+ ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
96+ where
97+
98+ throw =
99+ handling @EXCEPT @e @trans @m $
100+ coerce (T.throwError @e @(trans m) @a) ::
101+ forall eff a . e -> TaggedTrans eff trans m a
102+
103+ catch =
104+ handling @EXCEPT @e @trans @m $
105+ coerce (T.catchError @e @(trans m) @a) ::
106+ forall eff a . Catch e (TaggedTrans eff trans m) a
107+
108+type MonadExcept' e = MonadExcept e e
109+
110+throw' :: forall e m a . MonadExcept' e m => e -> m a
111+throw' = throw @e
112+
113+catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
114+catch' = catch @e
115+
116+type Except' e = Except e e
117+
118+runExcept' :: Except' e a -> Either e a
119+runExcept' = runExcept
120+
121+type ExceptT' e = ExceptT e e
122+
123+exceptT' :: m (Either e a) -> ExceptT' e m a
124+exceptT' = exceptT
125+
126+runExceptT' :: ExceptT' e m a -> m (Either e a)
127+runExceptT' = runExceptT
src/Ether/Internal.hsnew file+68
@@ -0,0 +1,68 @@
1+module Ether.Internal
2+ ( Tagged(..)
3+ , TagsK
4+ , Tags
5+ , HasLens(..)
6+ , LensLike
7+ , Lens
8+ , Lens'
9+ , ReifiedLens(..)
10+ , ReifiedLens'
11+ , view
12+ , over
13+ , HList(..)
14+ , KindOf
15+ , TAGGED
16+ , HandleSuper
17+ , HandleConstraint
18+ , Handle(..)
19+ , makeTupleInstancesHasLens
20+ ) where
21+
22+import Control.Applicative
23+import Data.Coerce
24+import Data.Functor.Identity
25+import Data.Kind
26+import Data.Tagged
27+import GHC.Exts (Constraint)
28+
29+import Ether.Internal.HasLens
30+import Ether.Internal.Tags
31+import Ether.Internal.TH_TupleInstances (makeTupleInstancesHasLens)
32+import Ether.Internal.TupleInstances ()
33+
34+data TAGGED e t
35+
36+type K_Monad = Type -> Type
37+
38+type K_Trans = K_Monad -> K_Monad
39+
40+type family
41+ HandleSuper
42+ (eff :: keff)
43+ (p :: kp)
44+ (trans :: K_Trans)
45+ :: Constraint
46+
47+type family
48+ HandleConstraint
49+ (eff :: keff)
50+ (p :: kp)
51+ (trans :: K_Trans) (m :: K_Monad)
52+ :: Constraint
53+
54+class
55+ HandleSuper eff p trans =>
56+ Handle eff p (trans :: K_Trans) | eff trans -> p
57+ where
58+ handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
59+
60+newtype ReifiedLens s t a b = Lens (Lens s t a b)
61+
62+type ReifiedLens' s a = ReifiedLens s s a a
63+
64+view :: LensLike (Const a) s t a b -> s -> a
65+view l = coerce (l Const)
66+
67+over :: LensLike Identity s t a b -> (a -> b) -> s -> t
68+over = coerce
src/Ether/Internal/HasLens.hsnew file+24
@@ -0,0 +1,24 @@
1+module Ether.Internal.HasLens
2+ ( LensLike
3+ , Lens
4+ , Lens'
5+ , HasLens(..)
6+ ) where
7+
8+import Data.Tagged
9+import Data.Coerce
10+
11+type LensLike f s t a b = (a -> f b) -> s -> f t
12+
13+type Lens s t a b = forall f. Functor f => LensLike f s t a b
14+
15+type Lens' s a = Lens s s a a
16+
17+class HasLens tag outer inner | tag outer -> inner where
18+ lensOf :: Lens' outer inner
19+
20+instance HasLens a a a where
21+ lensOf = id
22+
23+instance HasLens t (Tagged t a) a where
24+ lensOf = \f -> fmap coerce . f . coerce
src/Ether/Internal/TH_TupleInstances.hsnew file+79
@@ -0,0 +1,79 @@
1+module Ether.Internal.TH_TupleInstances
2+ ( makeTupleInstancesTagsK
3+ , makeTupleInstancesTags
4+ , makeTupleInstancesHasLens
5+ ) where
6+
7+import Data.Tagged
8+import Data.Traversable
9+import Data.List as List
10+import qualified Language.Haskell.TH as TH
11+
12+import Ether.Internal.HasLens
13+import Ether.Internal.Tags
14+import Ether.Internal.TH_Utils
15+
16+makeTupleInstancesTagsK :: TH.DecsQ
17+makeTupleInstancesTagsK = do
18+ for [2..tupCount] $ \n -> do
19+ let
20+ tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
21+ (\k -> TH.ConT ''Tagged `TH.AppT`
22+ TH.VarT (tagName k) `TH.AppT`
23+ TH.VarT (varName k)) <$> [0..n-1]
24+ tagsList = List.foldr
25+ (\a b -> TH.PromotedConsT `TH.AppT` a `TH.AppT` b)
26+ TH.PromotedNilT
27+ (TH.AppT (TH.ConT ''KindOf) . TH.VarT . tagName <$> [0..n-1])
28+ return $
29+ TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy] tagsList)
30+
31+makeTupleInstancesTags :: TH.DecsQ
32+makeTupleInstancesTags = do
33+ for [2..tupCount] $ \n -> do
34+ let
35+ tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
36+ (\k -> TH.ConT ''Tagged `TH.AppT`
37+ TH.VarT (tagName k) `TH.AppT`
38+ TH.VarT (varName k)) <$> [0..n-1]
39+ tagsList = List.foldr
40+ (\a b -> TH.PromotedT 'HCons `TH.AppT` a `TH.AppT` b)
41+ (TH.PromotedT 'HNil)
42+ (TH.VarT . tagName <$> [0..n-1])
43+ return $
44+ TH.TySynInstD ''Tags (TH.TySynEqn [tupTy] tagsList)
45+
46+makeTupleInstancesHasLens :: [Int] -> TH.DecsQ
47+makeTupleInstancesHasLens range = List.concat <$> do
48+ for range $ \n ->
49+ for [0..n-1] $ \k -> do
50+ let
51+ tag = TH.mkName "tag"
52+ prev = varName <$> [0..k-1]
53+ cur = varName k
54+ next = varName <$> [k+1..n-1]
55+ tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
56+ ( map TH.VarT prev ++
57+ [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
58+ map TH.VarT next )
59+ let
60+ cur' = TH.mkName "x"
61+ f = TH.mkName "f"
62+ return $
63+ TH.InstanceD Nothing []
64+ (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
65+ [ TH.FunD 'lensOf
66+ [ TH.Clause
67+ [TH.VarP f, TH.TupP
68+ ( map TH.VarP prev ++
69+ [TH.ConP 'Tagged [TH.VarP cur]] ++
70+ map TH.VarP next )]
71+ (TH.NormalB $
72+ TH.VarE 'fmap `TH.AppE`
73+ (TH.LamE [TH.VarP cur']
74+ (TH.TupE
75+ ( map TH.VarE prev ++
76+ [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
77+ map TH.VarE next ))) `TH.AppE`
78+ (TH.VarE f `TH.AppE` TH.VarE cur) )
79+ [] ] ]
src/Ether/Internal/TH_Utils.hsnew file+14
@@ -0,0 +1,14 @@
1+module Ether.Internal.TH_Utils
2+ ( tupCount
3+ , varName
4+ , tagName
5+ ) where
6+
7+import qualified Language.Haskell.TH as TH
8+
9+tupCount :: Int
10+tupCount = 62
11+
12+varName, tagName :: Int -> TH.Name
13+varName k = TH.mkName ('a' : show k)
14+tagName k = TH.mkName ('t' : show k)
src/Ether/Internal/Tags.hsnew file+18
@@ -0,0 +1,18 @@
1+module Ether.Internal.Tags
2+ ( Tags
3+ , TagsK
4+ , HList(..)
5+ , KindOf
6+ ) where
7+
8+import Data.Kind
9+
10+data HList xs where
11+ HNil :: HList '[]
12+ HCons :: x -> HList xs -> HList (x ': xs)
13+
14+type KindOf (a :: k) = k
15+
16+type family TagsK (p :: Type) :: [Type]
17+type family Tags (p :: Type) :: HList (TagsK p)
18+
src/Ether/Internal/TupleInstances.hsnew file+24
@@ -0,0 +1,24 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module Ether.Internal.TupleInstances () where
5+
6+import Data.Tagged
7+import Ether.Internal.Tags
8+import Ether.Internal.TH_TupleInstances
9+
10+type instance TagsK () = '[]
11+type instance TagsK (Tagged t a) = '[KindOf t]
12+type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
13+
14+makeTupleInstancesTagsK
15+
16+type instance Tags () = 'HNil
17+type instance Tags (Tagged t a) = 'HCons t 'HNil
18+type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
19+
20+makeTupleInstancesTags
21+
22+#ifndef DISABLE_TUP_INSTANCES
23+makeTupleInstancesHasLens [2..62]
24+#endif
src/Ether/Reader.hsnew file+236
@@ -0,0 +1,236 @@
1+module Ether.Reader
2+ (
3+ -- * MonadReader class
4+ MonadReader
5+ , ask
6+ , local
7+ , reader
8+ , asks
9+ -- * The Reader monad
10+ , Reader
11+ , runReader
12+ -- * The ReaderT monad transformer
13+ , ReaderT
14+ , readerT
15+ , runReaderT
16+ -- * The Reader monad (flattened)
17+ , Readers
18+ , runReaders
19+ -- * The ReaderT monad transformer (flattened)
20+ , ReadersT
21+ , runReadersT
22+ -- * MonadReader class (implicit)
23+ , MonadReader'
24+ , local'
25+ , ask'
26+ , reader'
27+ , asks'
28+ -- * The Reader monad (implicit)
29+ , Reader'
30+ , runReader'
31+ -- * The ReaderT monad transformer (implicit)
32+ , ReaderT'
33+ , readerT'
34+ , runReaderT'
35+ -- * Internal labels
36+ , TAGGED
37+ , READER
38+ , READERS
39+ ) where
40+
41+import qualified Control.Monad.Reader as T
42+import qualified Control.Monad.Trans.Lift.Local as Lift
43+import Control.Monad.Trans.Lift.Local (Local)
44+import Data.Coerce
45+import Data.Functor.Identity
46+import Data.Kind
47+
48+import Ether.TaggedTrans
49+import Ether.Internal
50+
51+class Monad m => MonadReader tag r m | m tag -> r where
52+
53+ {-# MINIMAL (ask | reader), local #-}
54+
55+ -- | Retrieves the monad environment.
56+ ask :: m r
57+ ask = reader @tag id
58+
59+ -- | Executes a computation in a modified environment.
60+ local
61+ :: (r -> r)
62+ -- ^ The function to modify the environment.
63+ -> m a
64+ -- ^ @Reader@ to run in the modified environment.
65+ -> m a
66+
67+ -- | Retrieves a function of the current environment.
68+ reader
69+ :: (r -> a)
70+ -- ^ The selector function to apply to the environment.
71+ -> m a
72+ reader f = fmap f (ask @tag)
73+
74+instance {-# OVERLAPPABLE #-}
75+ ( Lift.LiftLocal t
76+ , Monad (t m)
77+ , MonadReader tag r m
78+ ) => MonadReader tag r (t m)
79+ where
80+ ask = Lift.lift (ask @tag)
81+ local = Lift.liftLocal (ask @tag) (local @tag)
82+ reader = Lift.lift . reader @tag
83+
84+instance {-# OVERLAPPABLE #-}
85+ ( Monad (trans m)
86+ , MonadReader tag r (TaggedTrans effs trans m)
87+ ) => MonadReader tag r (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
88+ where
89+
90+ ask =
91+ (coerce ::
92+ TaggedTrans effs trans m r ->
93+ TaggedTrans (eff ': effs) trans m r)
94+ (ask @tag)
95+
96+ local =
97+ (coerce :: forall a .
98+ Lift.Local r (TaggedTrans effs trans m) a ->
99+ Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
100+ (local @tag)
101+
102+ reader =
103+ (coerce :: forall a .
104+ ((r -> a) -> TaggedTrans effs trans m a) ->
105+ ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
106+ (reader @tag)
107+
108+-- | Retrieves a function of the current environment.
109+asks
110+ :: forall tag r m a
111+ . MonadReader tag r m
112+ => (r -> a)
113+ -- ^ The selector function to apply to the environment.
114+ -> m a
115+asks = reader @tag
116+
117+-- | Encode type-level information for 'ReaderT'.
118+data READER
119+
120+-- | The parameterizable reader monad.
121+--
122+-- Computations are functions of a shared environment.
123+--
124+-- The 'return' function ignores the environment, while '>>=' passes
125+-- the inherited environment to both subcomputations.
126+type Reader tag r = ReaderT tag r Identity
127+
128+-- | The reader monad transformer,
129+-- which adds a read-only environment to the given monad.
130+--
131+-- The 'return' function ignores the environment, while '>>=' passes
132+-- the inherited environment to both subcomputations.
133+type ReaderT tag r = TaggedTrans (TAGGED READER tag) (T.ReaderT r)
134+
135+-- | Constructor for computations in the reader monad transformer.
136+readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
137+readerT = coerce (T.ReaderT @r @m @a)
138+
139+-- | Runs a 'ReaderT' with the given environment
140+-- and returns the final value.
141+runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
142+runReaderT = coerce (T.runReaderT @r @m @a)
143+
144+-- | Runs a 'ReaderT' with the given environment
145+-- and returns the final value.
146+runReader :: forall tag r a . Reader tag r a -> r -> a
147+runReader = coerce (T.runReader @r @a)
148+
149+type instance HandleSuper READER r trans = ()
150+type instance HandleConstraint READER r trans m =
151+ T.MonadReader r (trans m)
152+
153+instance Handle READER r (T.ReaderT r) where
154+ handling r = r
155+
156+instance
157+ ( Handle READER r trans
158+ , Monad m, Monad (trans m)
159+ ) => MonadReader tag r (TaggedTrans (TAGGED READER tag) trans m)
160+ where
161+
162+ ask =
163+ handling @READER @r @trans @m $
164+ coerce (T.ask @r @(trans m))
165+
166+ local =
167+ handling @READER @r @trans @m $
168+ coerce (T.local @r @(trans m) @a) ::
169+ forall eff a . Local r (TaggedTrans eff trans m) a
170+
171+ reader =
172+ handling @READER @r @trans @m $
173+ coerce (T.reader @r @(trans m) @a) ::
174+ forall eff a . (r -> a) -> TaggedTrans eff trans m a
175+
176+instance
177+ ( HasLens tag payload r
178+ , Handle READER payload trans
179+ , Monad m, Monad (trans m)
180+ ) => MonadReader tag r (TaggedTrans (TAGGED READER tag ': effs) trans m)
181+ where
182+
183+ ask =
184+ handling @READER @payload @trans @m $
185+ (coerce :: forall eff a .
186+ trans m a ->
187+ TaggedTrans eff trans m a)
188+ (T.asks (view (lensOf @tag @payload @r)))
189+
190+ local f =
191+ handling @READER @payload @trans @m $
192+ (coerce :: forall eff a .
193+ (trans m a -> trans m a) ->
194+ (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
195+ (T.local (over (lensOf @tag @payload @r) f))
196+
197+type family READERS (ts :: HList xs) :: [Type] where
198+ READERS 'HNil = '[]
199+ READERS ('HCons t ts) = TAGGED READER t ': READERS ts
200+
201+type ReadersT r = TaggedTrans (READERS (Tags r)) (T.ReaderT r)
202+
203+type Readers r = ReadersT r Identity
204+
205+runReadersT :: forall p m a . ReadersT p m a -> p -> m a
206+runReadersT = coerce (T.runReaderT @p @m @a)
207+
208+runReaders :: forall p a . Readers p a -> p -> a
209+runReaders = coerce (T.runReader @p @a)
210+
211+type ReaderT' r = ReaderT r r
212+
213+readerT' :: (r -> m a) -> ReaderT' r m a
214+readerT' = readerT
215+
216+runReaderT' :: ReaderT' r m a -> r -> m a
217+runReaderT' = runReaderT
218+
219+type Reader' r = Reader r r
220+
221+runReader' :: Reader' r a -> r -> a
222+runReader' = runReader
223+
224+type MonadReader' r = MonadReader r r
225+
226+local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
227+local' = local @r
228+
229+ask' :: forall r m . MonadReader' r m => m r
230+ask' = ask @r
231+
232+reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
233+reader' = reader @r
234+
235+asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
236+asks' = asks @r
src/Ether/State.hsnew file+415
@@ -0,0 +1,415 @@
1+module Ether.State
2+ (
3+ -- * MonadState class
4+ MonadState
5+ , get
6+ , put
7+ , state
8+ , modify
9+ , gets
10+ -- * The State monad
11+ , State
12+ , runState
13+ , evalState
14+ , execState
15+ -- * The StateT monad transformer
16+ , StateT
17+ , stateT
18+ , runStateT
19+ , evalStateT
20+ , execStateT
21+ -- * The State monad (lazy)
22+ , LazyState
23+ , runLazyState
24+ , evalLazyState
25+ , execLazyState
26+ -- * The StateT monad transformer (lazy)
27+ , LazyStateT
28+ , lazyStateT
29+ , runLazyStateT
30+ , evalLazyStateT
31+ , execLazyStateT
32+ -- * The State monad (flattened)
33+ , States
34+ , runStates
35+ -- * The StateT monad transformer (flattened)
36+ , StatesT
37+ , runStatesT
38+ -- * MonadState class (implicit)
39+ , MonadState'
40+ , get'
41+ , put'
42+ , state'
43+ , modify'
44+ , gets'
45+ -- * The State monad (implicit)
46+ , State'
47+ , runState'
48+ , evalState'
49+ , execState'
50+ -- * The StateT monad transformer (implicit)
51+ , StateT'
52+ , stateT'
53+ , runStateT'
54+ , evalStateT'
55+ , execStateT'
56+ -- * The State monad (lazy, implicit)
57+ , LazyState'
58+ , runLazyState'
59+ , evalLazyState'
60+ , execLazyState'
61+ -- * The StateT monad transformer (lazy, implicit)
62+ , LazyStateT'
63+ , lazyStateT'
64+ , runLazyStateT'
65+ , evalLazyStateT'
66+ , execLazyStateT'
67+ -- * Zoom
68+ , ZoomT
69+ , zoom
70+ -- * Internal labels
71+ , TAGGED
72+ , STATE
73+ , STATES
74+ , ZOOM
75+ ) where
76+
77+import qualified Control.Monad.State.Class as T
78+import qualified Control.Monad.Trans as Lift
79+import Control.Monad.Trans.Identity
80+import qualified Control.Monad.Trans.State.Lazy as T.Lazy
81+import qualified Control.Monad.Trans.State.Strict as T.Strict
82+import Data.Coerce
83+import Data.Functor.Identity
84+import Data.Kind
85+import Data.Proxy
86+import Data.Reflection
87+
88+import Ether.Internal
89+import Ether.TaggedTrans
90+
91+class Monad m => MonadState tag s m | m tag -> s where
92+
93+ {-# MINIMAL state | get, put #-}
94+
95+ -- | Return the state from the internals of the monad.
96+ get :: m s
97+ get = state @tag (\s -> (s, s))
98+
99+ -- | Replace the state inside the monad.
100+ put :: s -> m ()
101+ put s = state @tag (\_ -> ((), s))
102+
103+ -- | Embed a simple state action into the monad.
104+ state :: (s -> (a, s)) -> m a
105+ state f = do
106+ s <- get @tag
107+ let ~(a, s') = f s
108+ put @tag s'
109+ return a
110+
111+instance {-# OVERLAPPABLE #-}
112+ ( Lift.MonadTrans t
113+ , Monad (t m)
114+ , MonadState tag s m
115+ ) => MonadState tag s (t m)
116+ where
117+ get = Lift.lift (get @tag)
118+ put = Lift.lift . put @tag
119+ state = Lift.lift . state @tag
120+
121+instance {-# OVERLAPPABLE #-}
122+ ( Monad (trans m)
123+ , MonadState tag s (TaggedTrans effs trans m)
124+ ) => MonadState tag s (TaggedTrans (eff ': effs) trans (m :: Type -> Type))
125+ where
126+
127+ get =
128+ (coerce ::
129+ TaggedTrans effs trans m s ->
130+ TaggedTrans (eff ': effs) trans m s)
131+ (get @tag)
132+
133+ put =
134+ (coerce ::
135+ (s -> TaggedTrans effs trans m ()) ->
136+ (s -> TaggedTrans (eff ': effs) trans m ()))
137+ (put @tag)
138+
139+ state =
140+ (coerce :: forall a .
141+ ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
142+ ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
143+ (state @tag)
144+
145+-- | Modifies the state inside a state monad.
146+modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
147+modify f = state @tag (\s -> ((), f s))
148+
149+-- | Gets specific component of the state, using a projection function supplied.
150+gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
151+gets f = fmap f (get @tag)
152+
153+-- | Encode type-level information for 'StateT'.
154+data STATE
155+
156+type instance HandleSuper STATE s trans = ()
157+type instance HandleConstraint STATE s trans m =
158+ T.MonadState s (trans m)
159+
160+instance Handle STATE s (T.Strict.StateT s) where
161+ handling r = r
162+
163+instance Handle STATE s (T.Lazy.StateT s) where
164+ handling r = r
165+
166+instance
167+ ( Handle STATE s trans
168+ , Monad m, Monad (trans m)
169+ ) => MonadState tag s (TaggedTrans (TAGGED STATE tag) trans m)
170+ where
171+
172+ get =
173+ handling @STATE @s @trans @m $
174+ coerce (T.get @s @(trans m))
175+
176+ put =
177+ handling @STATE @s @trans @m $
178+ coerce (T.put @s @(trans m))
179+
180+ state =
181+ handling @STATE @s @trans @m $
182+ coerce (T.state @s @(trans m) @a) ::
183+ forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
184+
185+instance
186+ ( HasLens tag payload s
187+ , Handle STATE payload trans
188+ , Monad m, Monad (trans m)
189+ ) => MonadState tag s (TaggedTrans (TAGGED STATE tag ': effs) trans m)
190+ where
191+
192+ get =
193+ handling @STATE @payload @trans @m $
194+ (coerce :: forall eff a .
195+ trans m a ->
196+ TaggedTrans eff trans m a)
197+ (T.gets (view (lensOf @tag @payload @s)))
198+
199+ put s =
200+ handling @STATE @payload @trans @m $
201+ (coerce :: forall eff a .
202+ trans m a ->
203+ TaggedTrans eff trans m a)
204+ (T.modify (over (lensOf @tag @payload @s) (const s)))
205+
206+ state f =
207+ handling @STATE @payload @trans @m $
208+ (coerce :: forall eff a .
209+ trans m a ->
210+ TaggedTrans eff trans m a)
211+ (T.state (lensOf @tag @payload @s f))
212+
213+-- | The parametrizable state monad.
214+--
215+-- Computations have access to a mutable state.
216+--
217+-- The 'return' function leaves the state unchanged, while '>>=' uses
218+-- the final state of the first computation as the initial state of the second.
219+type State tag r = StateT tag r Identity
220+
221+-- | The state monad transformer.
222+--
223+-- The 'return' function leaves the state unchanged, while '>>=' uses
224+-- the final state of the first computation as the initial state of the second.
225+type StateT tag s = TaggedTrans (TAGGED STATE tag) (T.Strict.StateT s)
226+
227+-- | Constructor for computations in the state monad transformer.
228+stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
229+stateT = coerce (T.Strict.StateT @s @m @a)
230+
231+-- | Runs a 'StateT' with the given initial state
232+-- and returns both the final value and the final state.
233+runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
234+runStateT = coerce (T.Strict.runStateT @s @m @a)
235+
236+-- | Runs a 'StateT' with the given initial state
237+-- and returns the final value, discarding the final state.
238+evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
239+evalStateT = coerce (T.Strict.evalStateT @m @s @a)
240+
241+-- | Runs a 'StateT' with the given initial state
242+-- and returns the final state, discarding the final value.
243+execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
244+execStateT = coerce (T.Strict.execStateT @m @s @a)
245+
246+-- | Runs a 'State' with the given initial state
247+-- and returns both the final value and the final state.
248+runState :: forall tag s a . State tag s a -> s -> (a, s)
249+runState = coerce (T.Strict.runState @s @a)
250+
251+-- | Runs a 'State' with the given initial state
252+-- and returns the final value, discarding the final state.
253+evalState :: forall tag s a . State tag s a -> s -> a
254+evalState = coerce (T.Strict.evalState @s @a)
255+
256+-- | Runs a 'State' with the given initial state
257+-- and returns the final state, discarding the final value.
258+execState :: forall tag s a . State tag s a -> s -> s
259+execState = coerce (T.Strict.execState @s @a)
260+
261+-- | The parametrizable state monad.
262+--
263+-- Computations have access to a mutable state.
264+--
265+-- The 'return' function leaves the state unchanged, while '>>=' uses
266+-- the final state of the first computation as the initial state of the second.
267+type LazyState tag r = LazyStateT tag r Identity
268+
269+-- | The state monad transformer.
270+--
271+-- The 'return' function leaves the state unchanged, while '>>=' uses
272+-- the final state of the first computation as the initial state of the second.
273+type LazyStateT tag s = TaggedTrans (TAGGED STATE tag) (T.Lazy.StateT s)
274+
275+-- | Constructor for computations in the state monad transformer.
276+lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
277+lazyStateT = coerce (T.Lazy.StateT @s @m @a)
278+
279+-- | Runs a 'StateT' with the given initial state
280+-- and returns both the final value and the final state.
281+runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
282+runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
283+
284+-- | Runs a 'StateT' with the given initial state
285+-- and returns the final value, discarding the final state.
286+evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
287+evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
288+
289+-- | Runs a 'StateT' with the given initial state
290+-- and returns the final state, discarding the final value.
291+execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
292+execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
293+
294+-- | Runs a 'State' with the given initial state
295+-- and returns both the final value and the final state.
296+runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
297+runLazyState = coerce (T.Lazy.runState @s @a)
298+
299+-- | Runs a 'State' with the given initial state
300+-- and returns the final value, discarding the final state.
301+evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
302+evalLazyState = coerce (T.Lazy.evalState @s @a)
303+
304+-- | Runs a 'State' with the given initial state
305+-- and returns the final state, discarding the final value.
306+execLazyState :: forall tag s a . LazyState tag s a -> s -> s
307+execLazyState = coerce (T.Lazy.execState @s @a)
308+
309+type family STATES (ts :: HList xs) :: [Type] where
310+ STATES 'HNil = '[]
311+ STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
312+
313+type StatesT s = TaggedTrans (STATES (Tags s)) (T.Strict.StateT s)
314+
315+type States s = StatesT s Identity
316+
317+runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
318+runStatesT = coerce (T.Strict.runStateT @p @m @a)
319+
320+runStates :: forall p a . States p a -> p -> (a, p)
321+runStates = coerce (T.Strict.runState @p @a)
322+
323+type StateT' s = StateT s s
324+
325+stateT' :: (s -> m (a, s)) -> StateT' s m a
326+stateT' = stateT
327+
328+runStateT' :: StateT' s m a -> s -> m (a, s)
329+runStateT' = runStateT
330+
331+runState' :: State' s a -> s -> (a, s)
332+runState' = runState
333+
334+evalStateT' :: Monad m => StateT' s m a -> s -> m a
335+evalStateT' = evalStateT
336+
337+type State' s = State s s
338+
339+evalState' :: State' s a -> s -> a
340+evalState' = evalState
341+
342+execStateT' :: Monad m => StateT' s m a -> s -> m s
343+execStateT' = execStateT
344+
345+execState' :: State' s a -> s -> s
346+execState' = execState
347+
348+type LazyStateT' s = LazyStateT s s
349+
350+lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
351+lazyStateT' = lazyStateT
352+
353+runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
354+runLazyStateT' = runLazyStateT
355+
356+runLazyState' :: LazyState' s a -> s -> (a, s)
357+runLazyState' = runLazyState
358+
359+evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
360+evalLazyStateT' = evalLazyStateT
361+
362+type LazyState' s = LazyState s s
363+
364+evalLazyState' :: LazyState' s a -> s -> a
365+evalLazyState' = evalLazyState
366+
367+execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
368+execLazyStateT' = execLazyStateT
369+
370+execLazyState' :: LazyState' s a -> s -> s
371+execLazyState' = execLazyState
372+
373+type MonadState' s = MonadState s s
374+
375+get' :: forall s m . MonadState' s m => m s
376+get' = get @s
377+
378+gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
379+gets' = gets @s
380+
381+put' :: forall s m . MonadState' s m => s -> m ()
382+put' = put @s
383+
384+state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
385+state' = state @s
386+
387+modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
388+modify' = modify @s
389+
390+-- | Encode type-level information for 'zoom'.
391+data ZOOM t z
392+
393+type ZoomT t (z :: Type) = TaggedTrans (ZOOM t z) IdentityT
394+
395+-- | Zoom into a part of a state using a lens.
396+zoom
397+ :: forall tag sOuter sInner m a
398+ . Lens' sOuter sInner
399+ -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
400+ -> m a
401+zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
402+
403+instance
404+ ( MonadState tag sOuter m
405+ , Reifies z (ReifiedLens' sOuter sInner)
406+ , trans ~ IdentityT
407+ ) => MonadState tag sInner (TaggedTrans (ZOOM tag z) trans m)
408+ where
409+ state =
410+ (coerce :: forall eff r a .
411+ (r -> m a) ->
412+ (r -> TaggedTrans eff trans m a))
413+ (state @tag . l)
414+ where
415+ Lens l = reflect (Proxy :: Proxy z)
src/Ether/TagDispatch.hsnew file+138
@@ -0,0 +1,138 @@
1+{- |
2+
3+Type-level machinery to manipulate constraints on the monad
4+transformer stack.
5+
6+Out of the box it provides the following dispatch strategies:
7+
8+* 'tagAttach' to use functions defined using untagged monad classes
9+ as if they were defined using tagged ones.
10+
11+* 'tagReplace' to use functions defined using one tag
12+ as if they were defined using another one.
13+
14+> import Ether
15+> import Control.Monad.State as Mtl
16+>
17+> data Foo
18+> data Bar
19+>
20+> f :: Mtl.MonadState Int m => m String
21+> f = fmap show Mtl.get
22+>
23+> g :: Ether.MonadState Foo Int m => m String
24+> g = tagAttach @Foo f
25+>
26+> h :: Ether.MonadState Bar Int m => m String
27+> h = tagReplace @Foo @Bar g
28+
29+-}
30+
31+module Ether.TagDispatch
32+ (
33+ -- * The Tag Attach monad transformer
34+ TagAttachT
35+ , tagAttach
36+ -- * The Tag Replace monad transformer
37+ , TagReplaceT
38+ , tagReplace
39+ -- * Internal labels
40+ , TAG_ATTACH
41+ , TAG_REPLACE
42+ ) where
43+
44+import qualified Control.Monad.Error.Class as Mtl
45+import qualified Control.Monad.Reader.Class as Mtl
46+import qualified Control.Monad.State.Class as Mtl
47+import qualified Control.Monad.Writer.Class as Mtl
48+
49+import Ether.Except
50+import Ether.Reader
51+import Ether.State
52+import Ether.Writer
53+import Ether.TaggedTrans
54+
55+import Control.Monad.Trans.Identity
56+import Data.Coerce
57+
58+-- | Encode type-level information for 'tagAttach'.
59+data TAG_ATTACH t
60+
61+type TagAttachT t = TaggedTrans (TAG_ATTACH t) IdentityT
62+
63+-- | Attach a tag to untagged transformers.
64+tagAttach :: forall tag m a . TagAttachT tag m a -> m a
65+tagAttach = coerce (runIdentityT @_ @m @a)
66+
67+instance {-# OVERLAPPING #-}
68+ ( MonadReader tag r m, trans ~ IdentityT
69+ ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
70+ where
71+ ask = ask @tag
72+ local = local @tag
73+ reader = reader @tag
74+
75+instance {-# OVERLAPPING #-}
76+ ( MonadState tag s m, trans ~ IdentityT
77+ ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
78+ where
79+ get = get @tag
80+ put = put @tag
81+ state = state @tag
82+
83+instance {-# OVERLAPPING #-}
84+ ( MonadExcept tag e m, trans ~ IdentityT
85+ ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
86+ where
87+ throwError = throw @tag
88+ catchError = catch @tag
89+
90+instance {-# OVERLAPPING #-}
91+ ( MonadWriter tag w m, trans ~ IdentityT
92+ ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
93+ where
94+ writer = writer @tag
95+ tell = tell @tag
96+ listen = listen @tag
97+ pass = pass @tag
98+
99+-- | Encode type-level information for 'tagReplace'.
100+data TAG_REPLACE tOld tNew
101+
102+type TagReplaceT tOld tNew = TaggedTrans (TAG_REPLACE tOld tNew) IdentityT
103+
104+-- | Replace a tag with another tag.
105+tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
106+tagReplace = coerce (runIdentityT @_ @m @a)
107+
108+instance
109+ ( MonadReader tNew r m, trans ~ IdentityT
110+ ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
111+ where
112+ ask = ask @tNew
113+ local = local @tNew
114+ reader = reader @tNew
115+
116+instance
117+ ( MonadState tNew s m, trans ~ IdentityT
118+ ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
119+ where
120+ get = get @tNew
121+ put = put @tNew
122+ state = state @tNew
123+
124+instance
125+ ( MonadExcept tNew e m, trans ~ IdentityT
126+ ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
127+ where
128+ throw = throw @tNew
129+ catch = catch @tNew
130+
131+instance
132+ ( MonadWriter tNew w m, trans ~ IdentityT
133+ ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
134+ where
135+ writer = writer @tNew
136+ tell = tell @tNew
137+ listen = listen @tNew
138+ pass = pass @tNew
src/Ether/TaggedTrans.hsnew file+206
@@ -0,0 +1,206 @@
1+-- The use of ImpredicativeTypes here is safe, see discussion under GitHub issue
2+-- #35. It's only needed to allow the visible type application of a polytype.
3+{-# LANGUAGE ImpredicativeTypes #-}
4+
5+module Ether.TaggedTrans
6+ ( TaggedTrans(..)
7+ ) where
8+
9+import Control.Applicative
10+import Control.Monad (MonadPlus)
11+import Control.Monad.Fix (MonadFix)
12+import Control.Monad.Trans.Class (MonadTrans, lift)
13+import Control.Monad.IO.Class (MonadIO)
14+import Control.Monad.Morph (MFunctor(..), MMonad(..))
15+import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
16+
17+import qualified Control.Monad.Base as MB
18+import qualified Control.Monad.Trans.Control as MC
19+
20+import qualified Control.Monad.Trans.Lift.StT as Lift
21+import qualified Control.Monad.Trans.Lift.Local as Lift
22+import qualified Control.Monad.Trans.Lift.Catch as Lift
23+import qualified Control.Monad.Trans.Lift.Listen as Lift
24+import qualified Control.Monad.Trans.Lift.Pass as Lift
25+import qualified Control.Monad.Trans.Lift.CallCC as Lift
26+
27+import qualified Control.Monad.Cont.Class as Mtl
28+import qualified Control.Monad.Reader.Class as Mtl
29+import qualified Control.Monad.State.Class as Mtl
30+import qualified Control.Monad.Writer.Class as Mtl
31+import qualified Control.Monad.Error.Class as Mtl
32+
33+import GHC.Generics (Generic)
34+import Data.Coerce (coerce)
35+
36+newtype TaggedTrans tag trans m a = TaggedTrans (trans m a)
37+ deriving
38+ ( Generic
39+ , Functor, Applicative, Alternative, Monad, MonadPlus
40+ , MonadFix, MonadTrans, MonadIO
41+ , MonadThrow, MonadCatch, MonadMask )
42+
43+type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
44+
45+type Unpack tag trans m a = TaggedTrans tag trans m a -> trans m a
46+
47+instance
48+ ( MB.MonadBase b (trans m)
49+ ) => MB.MonadBase b (TaggedTrans tag trans m)
50+ where
51+ liftBase =
52+ (coerce :: forall a .
53+ (b a -> trans m a) ->
54+ (b a -> TaggedTrans tag trans m a))
55+ MB.liftBase
56+
57+instance
58+ ( MC.MonadTransControl trans
59+ ) => MC.MonadTransControl (TaggedTrans tag trans)
60+ where
61+ type StT (TaggedTrans tag trans) a = MC.StT trans a
62+
63+ liftWith = MC.defaultLiftWith
64+ (coerce :: Pack tag trans m a)
65+ (coerce :: Unpack tag trans m a)
66+
67+ restoreT = MC.defaultRestoreT
68+ (coerce :: Pack tag trans m a)
69+
70+type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
71+
72+newtype LiftBaseWith' b m a = LBW { unLBW :: LiftBaseWith b m a }
73+
74+coerceLiftBaseWith ::
75+ LiftBaseWith b (trans m) a ->
76+ LiftBaseWith b (TaggedTrans tag trans m) a
77+coerceLiftBaseWith lbw =
78+ unLBW (coerce (LBW lbw))
79+
80+instance
81+ ( MC.MonadBaseControl b (trans m)
82+ ) => MC.MonadBaseControl b (TaggedTrans tag trans m)
83+ where
84+ type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
85+
86+ liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
87+
88+ restoreM =
89+ (coerce :: forall a .
90+ (MC.StM (trans m) a -> trans m a) ->
91+ (MC.StM (trans m) a -> TaggedTrans tag trans m a))
92+ MC.restoreM
93+
94+type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
95+
96+instance Lift.LiftLocal trans => Lift.LiftLocal (TaggedTrans tag trans) where
97+ liftLocal =
98+ Lift.defaultLiftLocal
99+ (coerce :: Pack tag trans m a)
100+ (coerce :: Unpack tag trans m a)
101+
102+instance Lift.LiftCatch trans => Lift.LiftCatch (TaggedTrans tag trans) where
103+ liftCatch =
104+ Lift.defaultLiftCatch
105+ (coerce :: Pack tag trans m a)
106+ (coerce :: Unpack tag trans m a)
107+
108+instance Lift.LiftListen trans => Lift.LiftListen (TaggedTrans tag trans) where
109+ liftListen =
110+ Lift.defaultLiftListen
111+ (coerce :: Pack tag trans m a)
112+ (coerce :: Unpack tag trans m a)
113+
114+instance Lift.LiftPass trans => Lift.LiftPass (TaggedTrans tag trans) where
115+ liftPass =
116+ Lift.defaultLiftPass
117+ (coerce :: Pack tag trans m a)
118+ (coerce :: Unpack tag trans m a)
119+
120+instance Lift.LiftCallCC trans => Lift.LiftCallCC (TaggedTrans tag trans) where
121+ liftCallCC =
122+ Lift.defaultLiftCallCC
123+ (coerce :: Pack tag trans m a)
124+ (coerce :: Unpack tag trans m a)
125+ liftCallCC' =
126+ Lift.defaultLiftCallCC'
127+ (coerce :: Pack tag trans m a)
128+ (coerce :: Unpack tag trans m a)
129+
130+
131+-- Instances for mtl classes
132+
133+instance
134+ ( Mtl.MonadCont m
135+ , Lift.LiftCallCC trans
136+ , Monad (trans m)
137+ ) => Mtl.MonadCont (TaggedTrans tag trans m)
138+ where
139+ callCC = Lift.liftCallCC' Mtl.callCC
140+
141+instance
142+ ( Mtl.MonadReader r m
143+ , Lift.LiftLocal trans
144+ , Monad (trans m)
145+ ) => Mtl.MonadReader r (TaggedTrans tag trans m)
146+ where
147+ ask = lift Mtl.ask
148+ local = Lift.liftLocal Mtl.ask Mtl.local
149+ reader = lift . Mtl.reader
150+
151+instance
152+ ( Mtl.MonadState s m
153+ , MonadTrans trans
154+ , Monad (trans m)
155+ ) => Mtl.MonadState s (TaggedTrans tag trans m)
156+ where
157+ get = lift Mtl.get
158+ put = lift . Mtl.put
159+ state = lift . Mtl.state
160+
161+instance
162+ ( Mtl.MonadWriter w m
163+ , Lift.LiftListen trans
164+ , Lift.LiftPass trans
165+ , Monad (trans m)
166+ ) => Mtl.MonadWriter w (TaggedTrans tag trans m)
167+ where
168+ writer = lift . Mtl.writer
169+ tell = lift . Mtl.tell
170+ listen = Lift.liftListen Mtl.listen
171+ pass = Lift.liftPass Mtl.pass
172+
173+instance
174+ ( Mtl.MonadError e m
175+ , Lift.LiftCatch trans
176+ , Monad (trans m)
177+ ) => Mtl.MonadError e (TaggedTrans tag trans m)
178+ where
179+ throwError = lift . Mtl.throwError
180+ catchError = Lift.liftCatch Mtl.catchError
181+
182+type Hoist trans =
183+ forall m n b . Monad m =>
184+ (forall a . m a -> n a) -> trans m b -> trans n b
185+
186+-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
187+-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
188+instance MFunctor trans => MFunctor (TaggedTrans tag trans) where
189+ hoist =
190+ coerce
191+ @(Hoist trans)
192+ @(Hoist (TaggedTrans tag trans))
193+ hoist
194+
195+type Embed trans =
196+ forall n m b . Monad n =>
197+ (forall a . m a -> trans n a) -> trans m b -> trans n b
198+
199+-- NB: Don't use GeneralizedNewtypeDeriving to create this instance, as it will
200+-- trigger GHC Trac #11837 on GHC 8.0.1 and older.
201+instance MMonad trans => MMonad (TaggedTrans tag trans) where
202+ embed =
203+ coerce
204+ @(Embed trans)
205+ @(Embed (TaggedTrans tag trans))
206+ embed
src/Ether/Writer.hsnew file+287
@@ -0,0 +1,287 @@
1+module Ether.Writer
2+ (
3+ -- * MonadWriter class
4+ MonadWriter
5+ , writer
6+ , tell
7+ , listen
8+ , pass
9+ , listens
10+ , censor
11+ -- * The Writer monad
12+ , Writer
13+ , runWriter
14+ , execWriter
15+ -- * The WriterT monad transformer
16+ , WriterT
17+ , writerT
18+ , runWriterT
19+ , execWriterT
20+ -- * The Writer monad (lazy)
21+ , LazyWriter
22+ , runLazyWriter
23+ , execLazyWriter
24+ -- * The WriterT monad transformer (lazy)
25+ , LazyWriterT
26+ , lazyWriterT
27+ , runLazyWriterT
28+ , execLazyWriterT
29+ -- * MonadWriter class (implicit)
30+ , MonadWriter'
31+ , writer'
32+ , tell'
33+ , listen'
34+ , pass'
35+ , listens'
36+ , censor'
37+ -- * The Writer monad (implicit)
38+ , Writer'
39+ , runWriter'
40+ , execWriter'
41+ -- * The WriterT monad transformer (implicit)
42+ , WriterT'
43+ , writerT'
44+ , runWriterT'
45+ , execWriterT'
46+ -- * The Writer monad (lazy, implicit)
47+ , LazyWriter'
48+ , runLazyWriter'
49+ , execLazyWriter'
50+ -- * The WriterT monad transformer (lazy, implicit)
51+ , LazyWriterT'
52+ , lazyWriterT'
53+ , runLazyWriterT'
54+ , execLazyWriterT'
55+ -- * Internal labels
56+ , TAGGED
57+ , WRITER
58+ ) where
59+
60+import Control.Monad.Signatures (Listen, Pass)
61+import qualified Control.Monad.Trans.Lift.Listen as Lift
62+import qualified Control.Monad.Trans.Lift.Pass as Lift
63+import qualified Control.Monad.Writer.Class as T
64+import qualified Control.Monad.Writer.CPS as T.CPS
65+import qualified Control.Monad.Writer.Lazy as T.Lazy
66+import Data.Coerce
67+import Data.Functor.Identity
68+
69+import Ether.Internal
70+import Ether.TaggedTrans
71+
72+class (Monoid w, Monad m) => MonadWriter tag w m | m tag -> w where
73+
74+ {-# MINIMAL (writer | tell), listen, pass #-}
75+
76+ -- | Embed a simple writer action.
77+ writer :: (a, w) -> m a
78+ writer ~(a, w) = a <$ tell @tag w
79+
80+ -- | Append a value to the accumulator within the monad.
81+ tell :: w -> m ()
82+ tell w = writer @tag ((),w)
83+
84+ -- | Execute an action and add its accumulator
85+ -- to the value of the computation.
86+ listen :: m a -> m (a, w)
87+
88+ -- | Execute an action which returns a value and a function,
89+ -- and return the value, applying the function to the accumulator.
90+ pass :: m (a, w -> w) -> m a
91+
92+instance {-# OVERLAPPABLE #-}
93+ ( Lift.LiftListen t
94+ , Lift.LiftPass t
95+ , Monad (t m)
96+ , MonadWriter tag w m
97+ , Monoid w
98+ ) => MonadWriter tag w (t m) where
99+ writer = Lift.lift . writer @tag
100+ tell = Lift.lift . tell @tag
101+ listen = Lift.liftListen (listen @tag)
102+ pass = Lift.liftPass (pass @tag)
103+
104+-- | Execute an action and add the result of applying the given function to
105+-- its accumulator to the value of the computation.
106+listens :: forall tag w m a b . MonadWriter tag w m => (w -> b) -> m a -> m (a, b)
107+listens f m = do
108+ ~(a, w) <- listen @tag m
109+ return (a, f w)
110+
111+-- | Execute an action and apply a function to its accumulator.
112+censor :: forall tag w m a . MonadWriter tag w m => (w -> w) -> m a -> m a
113+censor f m = pass @tag $ do
114+ a <- m
115+ return (a, f)
116+
117+-- | Encode type-level information for 'WriterT'.
118+data WRITER
119+
120+type instance HandleSuper WRITER w trans = Monoid w
121+type instance HandleConstraint WRITER w trans m =
122+ T.MonadWriter w (trans m)
123+
124+instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
125+ handling r = r
126+
127+instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
128+ handling r = r
129+
130+instance
131+ ( Handle WRITER w trans
132+ , Monad m, Monad (trans m)
133+ ) => MonadWriter tag w (TaggedTrans (TAGGED WRITER tag) trans m)
134+ where
135+
136+ writer =
137+ handling @WRITER @w @trans @m $
138+ coerce (T.writer @w @(trans m) @a) ::
139+ forall eff a . (a, w) -> TaggedTrans eff trans m a
140+
141+ tell =
142+ handling @WRITER @w @trans @m $
143+ coerce (T.tell @w @(trans m))
144+
145+ listen =
146+ handling @WRITER @w @trans @m $
147+ coerce (T.listen @w @(trans m) @a) ::
148+ forall eff a . Listen w (TaggedTrans eff trans m) a
149+
150+ pass =
151+ handling @WRITER @w @trans @m $
152+ coerce (T.pass @w @(trans m) @a) ::
153+ forall eff a . Pass w (TaggedTrans eff trans m) a
154+
155+-- | The parametrizable writer monad.
156+--
157+-- Computations can accumulate a monoid value.
158+--
159+-- The 'return' function produces the output 'mempty', while '>>=' combines
160+-- the outputs of the subcomputations using 'mappend'.
161+type Writer tag w = WriterT tag w Identity
162+
163+-- | The writer monad transformer.
164+--
165+-- The 'return' function produces the output 'mempty', while '>>=' combines
166+-- the outputs of the subcomputations using 'mappend'.
167+type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
168+
169+-- | Constructor for computations in the writer monad transformer.
170+writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
171+writerT = coerce (T.CPS.writerT @m @w @a)
172+
173+-- | Runs a 'WriterT' and returns both the normal value
174+-- and the final accumulator.
175+runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
176+runWriterT = coerce (T.CPS.runWriterT @w @m @a)
177+
178+-- | Runs a 'Writer' and returns both the normal value
179+-- and the final accumulator.
180+runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
181+runWriter = coerce (T.CPS.runWriter @w @a)
182+
183+-- | Runs a 'WriterT' and returns the final accumulator,
184+-- discarding the normal value.
185+execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
186+execWriterT = coerce (T.CPS.execWriterT @m @w @a)
187+
188+-- | Runs a 'Writer' and returns the final accumulator,
189+-- discarding the normal value.
190+execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
191+execWriter = coerce (T.CPS.execWriter @w @a)
192+
193+-- | The parametrizable writer monad.
194+--
195+-- Computations can accumulate a monoid value.
196+--
197+-- The 'return' function produces the output 'mempty', while '>>=' combines
198+-- the outputs of the subcomputations using 'mappend'.
199+type LazyWriter tag w = LazyWriterT tag w Identity
200+
201+-- | The writer monad transformer.
202+--
203+-- The 'return' function produces the output 'mempty', while '>>=' combines
204+-- the outputs of the subcomputations using 'mappend'.
205+type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
206+
207+-- | Constructor for computations in the writer monad transformer.
208+lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
209+lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
210+
211+-- | Runs a 'WriterT' and returns both the normal value
212+-- and the final accumulator.
213+runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
214+runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
215+
216+-- | Runs a 'Writer' and returns both the normal value
217+-- and the final accumulator.
218+runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
219+runLazyWriter = coerce (T.Lazy.runWriter @w @a)
220+
221+-- | Runs a 'WriterT' and returns the final accumulator,
222+-- discarding the normal value.
223+execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
224+execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
225+
226+-- | Runs a 'Writer' and returns the final accumulator,
227+-- discarding the normal value.
228+execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
229+execLazyWriter = coerce (T.Lazy.execWriter @w @a)
230+
231+type Writer' w = Writer w w
232+
233+runWriter' :: Monoid w => Writer' w a -> (a, w)
234+runWriter' = runWriter
235+
236+execWriter' :: Monoid w => Writer' w a -> w
237+execWriter' = execWriter
238+
239+type WriterT' w = WriterT w w
240+
241+writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
242+writerT' = writerT
243+
244+runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
245+runWriterT' = runWriterT
246+
247+execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
248+execWriterT' = execWriterT
249+
250+type LazyWriter' w = LazyWriter w w
251+
252+runLazyWriter' :: LazyWriter' w a -> (a, w)
253+runLazyWriter' = runLazyWriter
254+
255+execLazyWriter' :: LazyWriter' w a -> w
256+execLazyWriter' = execLazyWriter
257+
258+type LazyWriterT' w = LazyWriterT w w
259+
260+lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
261+lazyWriterT' = lazyWriterT
262+
263+runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
264+runLazyWriterT' = runLazyWriterT
265+
266+execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
267+execLazyWriterT' = execLazyWriterT
268+
269+type MonadWriter' w = MonadWriter w w
270+
271+writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
272+writer' = writer @w
273+
274+tell' :: forall w m . MonadWriter' w m => w -> m ()
275+tell' = tell @w
276+
277+listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
278+listen' = listen @w
279+
280+pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
281+pass' = pass @w
282+
283+listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
284+listens' = listens @w
285+
286+censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
287+censor' = censor @w
stack-ghc-7.8.4.yamldeleted−35
@@ -1,35 +0,0 @@
1−flags:
2− text:
3− integer-simple: false
4− QuickCheck:
5− base4point8: false
6−packages:
7−- '.'
8−extra-deps:
9−- QuickCheck-2.8.1
10−- ansi-terminal-0.6.2.3
11−- ansi-wl-pprint-0.6.7.3
12−- async-2.0.2
13−- clock-0.5.1
14−- mmorph-1.0.4
15−- monad-control-1.0.0.4
16−- mtl-2.2.1
17−- optparse-applicative-0.12.0.0
18−- parsec-3.1.9
19−- primitive-0.6.1.0
20−- random-1.1
21−- regex-base-0.93.2
22−- regex-tdfa-rc-1.1.8.3
23−- stm-2.4.4
24−- tagged-0.8.1
25−- tasty-0.11.0.1
26−- tasty-quickcheck-0.8.4
27−- text-1.2.1.3
28−- tf-random-0.5
29−- transformers-0.4.3.0
30−- transformers-base-0.4.4
31−- transformers-compat-0.4.0.4
32−- transformers-lift-0.1.0.0
33−- unbounded-delays-0.1.0.9
34−- exceptions-0.8.0.2
35−resolver: ghc-7.8.4
stack.yamldeleted−5
@@ -1,5 +0,0 @@
1−flags: {}
2−packages:
3−- '.'
4−extra-deps: []
5−resolver: lts-3.10
test/Regression.hs+8
@@ -10,6 +10,10 @@ import Regression.T5
1010import Regression.T6
1111import Regression.T7
1212import Regression.T8
13+import Regression.T9
14+import Regression.T10
15+import Regression.T11
16+import Regression.T12
1317
1418main :: IO ()
1519main = defaultMain suite
@@ -24,4 +28,8 @@ suite = testGroup "Ether"
2428 , test6
2529 , test7
2630 , test8
31+ , test9
32+ , test10
33+ , test11
34+ , test12
2735 ]
test/Regression/T1.hs+25−14
@@ -1,29 +1,34 @@
11module Regression.T1 (test1) where
22
3−import Control.Monad.Ether
4−import Control.Ether.Abbr
3+import Ether
4+import TupleInstances ()
5+import Data.List (group)
56
67import Test.Tasty
78import Test.Tasty.QuickCheck
89
9−ethereal "Tag1" "tag1"
10−ethereal "Tag2" "tag2"
10+data Tag1
11+data Tag2
1112
1213testEther
13− :: Ether '[Tag1 --> String, Tag2 --> String] m
14+ :: (MonadReader Tag1 String m, MonadReader Tag2 String m)
1415 => m ((String, String), (String, String))
1516testEther = do
16− s1 <- ask tag1
17− s2 <- ask tag2
17+ s1 <- ask @Tag1
18+ s2 <- ask @Tag2
1819 let s1s2 = (s1, s2)
19− s1s2' <- local tag2 (map succ) $ do
20− s1' <- ask tag1
21− s2' <- ask tag2
20+ s1s2' <- local @Tag2 (map succ) $ do
21+ s1' <- ask @Tag1
22+ s2' <- ask @Tag2
2223 return (s1', s2')
2324 return (s1s2, s1s2')
2425
25−runner1 s1 s2 = flip (runReader tag1) s1 . flip (runReaderT tag2) s2
26−runner2 s1 s2 = flip (runReader tag2) s2 . flip (runReaderT tag1) s1
26+runner1 s1 s2 = flip (runReader @Tag1) s1 . flip (runReaderT @Tag2) s2
27+runner2 s1 s2 = flip (runReader @Tag2) s2 . flip (runReaderT @Tag1) s1
28+runner3 s1 s2 = flip runReaders (Tagged @Tag1 s1, Tagged @Tag2 s2)
29+
30+same :: Eq a => [a] -> Bool
31+same = (<=1) . length . group
2732
2833test1 :: TestTree
2934test1 = testGroup "T1: Reader local environment"
@@ -33,7 +38,13 @@ test1 = testGroup "T1: Reader local environment"
3338 , testProperty "runner₂ works"
3439 $ \s1 s2 -> property
3540 $ runner2 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
36− , testProperty "runner₁ == runner₂"
41+ , testProperty "runner₃ works"
42+ $ \s1 s2 -> property
43+ $ runner3 s1 s2 testEther == ((s1, s2), (s1, map succ s2))
44+ , testProperty "runner₁ == runner₂ == runner₃"
3745 $ \s1 s2 -> property
38− $ runner1 s1 s2 testEther == runner2 s1 s2 testEther
46+ $ same
47+ [ runner1 s1 s2 testEther
48+ , runner2 s1 s2 testEther
49+ , runner3 s1 s2 testEther ]
3950 ]
test/Regression/T10.hsnew file+43
@@ -0,0 +1,43 @@
1+module Regression.T10 (test10) where
2+
3+import Control.Applicative
4+import Data.Functor.Identity
5+
6+import Ether
7+
8+import Test.Tasty
9+import Test.Tasty.QuickCheck
10+
11+testEther :: Integer -> StateT' Integer Maybe [Integer]
12+testEther m = range
13+ where
14+ range = liftA2 (:) yield (range <|> pure [])
15+ yield = stateT' $ \n -> do
16+ guard (n <= m)
17+ Just (n, n + 1)
18+
19+testEther' :: Integer -> State' Integer [Integer]
20+testEther' m =
21+ stateT' $ Identity . maybe ([], m + 1) id . runStateT' (testEther m)
22+
23+next1 :: Integer -> Integer -> Maybe Integer
24+next1 m n
25+ | n <= m = Just (m + 1)
26+ | otherwise = Nothing
27+
28+range1 :: Integer -> Integer -> Maybe [Integer]
29+range1 m n
30+ | n <= m = Just [n..m]
31+ | otherwise = Nothing
32+
33+test10 :: TestTree
34+test10 = testGroup "T10: Alternative instance"
35+ [ testProperty "execStateT works"
36+ $ \m n -> execStateT' (testEther m) n == next1 m n
37+ , testProperty "evalStateT works"
38+ $ \m n -> evalStateT' (testEther m) n == range1 m n
39+ , testProperty "execState works"
40+ $ \m n -> execState' (testEther' m) n == m + 1
41+ , testProperty "evalState works"
42+ $ \m n -> evalState' (testEther' m) n == [n..m]
43+ ]
test/Regression/T11.hsnew file+50
@@ -0,0 +1,50 @@
1+module Regression.T11 (test11) where
2+
3+import Ether
4+
5+import Data.Bool
6+import qualified Control.Monad.State as T
7+import qualified Control.Monad.Reader as T
8+
9+import Test.Tasty
10+import Test.Tasty.QuickCheck
11+
12+data STag
13+
14+testEther
15+ :: ( MonadState STag [Integer] m
16+ , T.MonadState Bool m
17+ , T.MonadReader Integer m )
18+ => m ()
19+testEther = do
20+ T.modify not
21+ f <- bool negate id <$> T.get
22+ n <- T.ask
23+ T.local succ testEther
24+ modify @STag (f n:)
25+
26+model :: Integer -> [Integer]
27+model n = zipWith ($) (cycle [id, negate]) [n..]
28+
29+runner1 n
30+ = flip (T.runReader) n
31+ . flip (execLazyStateT @STag) []
32+ . flip T.evalStateT False
33+
34+runner2 n
35+ = flip T.evalState False
36+ . flip (execLazyStateT @STag) []
37+ . flip T.runReaderT n
38+
39+test11 :: TestTree
40+test11 = testGroup "T11: Lazy sequence"
41+ [ testProperty "runner₁ works"
42+ $ \l n -> property
43+ $ take l (runner1 n testEther) == take l (model n)
44+ , testProperty "runner₂ works"
45+ $ \l n -> property
46+ $ take l (runner2 n testEther) == take l (model n)
47+ , testProperty "runner₁ == runner₂"
48+ $ \l n -> property
49+ $ take l (runner1 n testEther) == take l (runner2 n testEther)
50+ ]
test/Regression/T12.hsnew file+30
@@ -0,0 +1,30 @@
1+module Regression.T12 (test12) where
2+
3+import Ether
4+import Control.Lens
5+
6+import Test.Tasty
7+import Test.Tasty.QuickCheck
8+
9+data Foo
10+
11+succState :: Enum a => MonadState Foo a m => m ()
12+succState = modify @Foo succ
13+
14+testEther :: (Enum a, MonadState Foo (a, a) m) => m (a, a)
15+testEther = do
16+ Ether.zoom @Foo _1 succState
17+ Ether.zoom @Foo _2 $ modify @Foo pred
18+ get @Foo
19+
20+model :: Enum a => (a, a) -> (a, a)
21+model (a1, a2) = (succ a1, pred a2)
22+
23+runner = evalState @Foo
24+
25+test12 :: TestTree
26+test12 = testGroup "T12: State zooming"
27+ [ testProperty "runner works"
28+ $ \(a1 :: Integer, a2 :: Integer) -> property
29+ $ runner testEther (a1, a2) == model (a1, a2)
30+ ]
test/Regression/T2.hs+9−11
@@ -1,29 +1,27 @@
11module Regression.T2 (test2) where
22
3−import Control.Ether.Abbr
4−import qualified Control.Monad.Ether.Implicit as I
5−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
64
75import Test.Tasty
86import Test.Tasty.QuickCheck
97
10−testEther :: Ether '[I.R Integer, I.R Bool] m => m String
11−testEther = I.local (succ :: Integer -> Integer) $ do
12− n :: Integer <- I.ask
13− b <- I.local not I.ask
8+testEther :: (MonadReader' Integer m, MonadReader' Bool m) => m String
9+testEther = local' (succ :: Integer -> Integer) $ do
10+ n :: Integer <- asks' (*2)
11+ b <- local' not ask'
1412 return (if b then "" else show n)
1513
16−runner1 (n :: Integer) = flip I.runReader n . flip I.runReaderT True
17−runner2 (n :: Integer) = flip I.runReader True . flip I.runReaderT n
14+runner1 (n :: Integer) = flip runReader' n . flip runReaderT' True
15+runner2 (n :: Integer) = flip runReader' True . flip runReaderT' n
1816
1917test2 :: TestTree
2018test2 = testGroup "T2: Implicit tags"
2119 [ testProperty "runner₁ works"
2220 $ \n -> property
23− $ runner1 n testEther == show (succ n)
21+ $ runner1 n testEther == show (succ n * 2)
2422 , testProperty "runner₂ works"
2523 $ \n -> property
26− $ runner2 n testEther == show (succ n)
24+ $ runner2 n testEther == show (succ n * 2)
2725 , testProperty "runner₁ == runner₂"
2826 $ \n -> property
2927 $ runner1 n testEther == runner2 n testEther
test/Regression/T3.hs+15−16
@@ -1,7 +1,6 @@
11module Regression.T3 (test3) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.Reader as T
76import qualified Control.Monad.State as T
@@ -9,8 +8,8 @@ import qualified Control.Monad.State as T
98import Test.Tasty
109import Test.Tasty.QuickCheck
1110
12−ethereal "RTag" "rTag"
13−ethereal "STag" "sTag"
11+data RTag
12+data STag
1413
1514testMTL :: (T.MonadReader Int m, T.MonadState Int m) => m Int
1615testMTL = do
@@ -20,23 +19,23 @@ testMTL = do
2019 return (a * b)
2120
2221testEther
23− :: Ether '[STag --> Int, STag <-> Int, RTag --> Int] m
22+ :: (MonadReader STag Int m, MonadState STag Int m, MonadReader RTag Int m)
2423 => m (Int, Int, Int)
25−testEther = local rTag (*2) $ do
26− a_mul_b <- tagAttach sTag testMTL
27− a_add_b <- get sTag
28− modify sTag negate
29− c <- ask rTag
24+testEther = local @RTag (*2) $ do
25+ a_mul_b <- tagAttach @STag testMTL
26+ a_add_b <- get @STag
27+ modify @STag negate
28+ c <- ask @RTag
3029 return (a_mul_b, a_add_b, c)
3130
3231runner1 s r
33− = flip (runReader rTag) (negate r)
34− . flip (runReaderT sTag) r
35− . flip (runStateT sTag) s
32+ = flip (runReader @RTag) (negate r)
33+ . flip (runReaderT @STag) r
34+ . flip (runStateT @STag) s
3635runner2 s r
37− = flip (runReader rTag) (negate r)
38− . flip (runStateT sTag) s
39− . flip (runReaderT sTag) r
36+ = flip (runReader @RTag) (negate r)
37+ . flip (runStateT @STag) s
38+ . flip (runReaderT @STag) r
4039
4140test3 :: TestTree
4241test3 = testGroup "T3: Tag attachement"
test/Regression/T4.hs+6−8
@@ -1,20 +1,18 @@
11module Regression.T4 (test4) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import Test.Tasty
76import Test.Tasty.QuickCheck
87
9−ethereal "RTag" "rTag"
8+data RTag
109
11−testEther :: Ether '[RTag --> Int] m => m Int
12−testEther = ask rTag
10+testEther :: MonadReader RTag Int m => m Int
11+testEther = ask @RTag
1312
1413runner r
15− = flip (runReader rTag) (r' :: Int)
16− . flip (runReaderT rTag) (r :: Int)
17− . flip (runReaderT rTag) (fromIntegral r' :: Integer)
14+ = flip (runReader @RTag) (r' :: Int)
15+ . flip (runReaderT @RTag) (r :: Int)
1816 where
1917 r' = negate r
2018
test/Regression/T5.hs+8−11
@@ -1,9 +1,6 @@
11module Regression.T5 (test5) where
22
3−import Control.Ether.Abbr
4−
5−import qualified Control.Monad.Ether.Implicit as I
6−import qualified Control.Ether.Implicit.Abbr as I
3+import Ether
74
85import Test.Tasty
96import Test.Tasty.QuickCheck
@@ -16,22 +13,22 @@ incCounter = succ
1613
1714testEther
1815 :: (Num a, Ord a)
19− => Ether '[I.R a, I.S Counter] m
16+ => (MonadReader' a m, MonadState' Counter m)
2017 => m a
2118testEther = do
22− a <- I.ask
19+ a <- ask'
2320 if a <= 0
2421 then do
25− I.put (0 :: Counter)
22+ put' (0 :: Counter)
2623 return 1
2724 else do
28− I.modify incCounter -- overriden in the base case
29− b <- I.runReaderT testEther (a - 1)
30− I.modify incCounter
25+ modify' incCounter -- overriden in the base case
26+ b <- runReaderT' testEther (a - 1)
27+ modify' incCounter
3128 return (a * b)
3229
3330runner :: (Num a, Ord a) => a -> (a, Counter)
34−runner a = I.runState (I.runReaderT testEther a) (0 :: Counter)
31+runner a = runState' (runReaderT' testEther a) (0 :: Counter)
3532
3633factorial :: (Num a, Enum a) => a -> a
3734factorial a = product [1..a]
test/Regression/T6.hs+14−16
@@ -1,10 +1,7 @@
11module Regression.T6 (test6) where
22
3−import Control.Monad
4−import Control.Ether.Abbr
5−
6−import qualified Control.Monad.Ether.Implicit as I
7−import qualified Control.Ether.Implicit.Abbr as I
3+import Data.Function
4+import Ether
85
96import Test.Tasty
107import Test.Tasty.QuickCheck
@@ -17,32 +14,33 @@ data NegativeLog a = NegativeLog a
1714
1815testEther
1916 :: (Floating a, Ord a)
20− => Ether '[I.E DivideByZero, I.E (NegativeLog a)] m
17+ => (MonadExcept' DivideByZero m, MonadExcept' (NegativeLog a) m)
2118 => a -> a -> m a
2219testEther a b = do
23− when (b == 0) (I.throw DivideByZero)
20+ when (b == 0) (throw' DivideByZero)
2421 let d = a / b
25− when (d < 0) (I.throw (NegativeLog d))
22+ when (d < 0) (throw' (NegativeLog d))
2623 return (log d)
2724
28−-- Copied verbatim from "Data.Function" to support @base < 4.8@.
29−(&) :: a -> (a -> b) -> b
30−x & f = f x
31−
3225handleNegativeLog (NegativeLog (x :: Double)) = "nl: " ++ show x
3326handleDivideByZero DivideByZero = "dz"
3427
28+handleT' :: Functor m => (e -> a) -> ExceptT' e m a -> m a
29+handleT' h m = fmap (either h id) (runExceptT' m)
30+
3531runner1 :: Double -> Double -> String
3632runner1 a b = do
3733 (show `fmap` testEther a b)
38− & I.handleT handleNegativeLog
39− & I.handle handleDivideByZero
34+ & handleT' handleNegativeLog
35+ & handleT' handleDivideByZero
36+ & runIdentity
4037
4138runner2 :: Double -> Double -> String
4239runner2 a b = do
4340 (show `fmap` testEther a b)
44− & I.handleT handleDivideByZero
45− & I.handle handleNegativeLog
41+ & handleT' handleDivideByZero
42+ & handleT' handleNegativeLog
43+ & runIdentity
4644
4745logDiv :: Double -> Double -> String
4846logDiv a b
test/Regression/T7.hs+7−6
@@ -3,13 +3,13 @@ module Regression.T7 (test7) where
33import Data.Monoid
44import Control.Monad
55
6−import Control.Monad.Ether
6+import Ether
77import qualified Control.Monad.Writer as T
88
99import Test.Tasty
1010import Test.Tasty.QuickCheck
1111
12−ethereal "WTag" "wTag"
12+data WTag
1313
1414testEther
1515 :: Num a
@@ -18,17 +18,18 @@ testEther
1818 => [a] -> m ()
1919testEther xs = do
2020 forM_ xs $ \x -> do
21− T.tell (Sum x)
22− tell wTag (Sum 1)
21+ u1 <- T.tell (Sum x)
22+ u2 <- tell @WTag (Sum 1)
23+ when (u1 /= u2) $ error "Impossible"
2324
2425runner1 :: Num a => [a] -> (a, a)
2526runner1 xs =
26− let (s, c) = T.runWriter . execWriterT wTag $ testEther xs
27+ let (s, c) = T.runWriter . execWriterT @WTag $ testEther xs
2728 in (getSum s, getSum c)
2829
2930runner2 :: Num a => [a] -> (a, a)
3031runner2 xs =
31− let (c, s) = runWriter wTag . T.execWriterT $ testEther xs
32+ let (c, s) = runWriter @WTag . T.execWriterT $ testEther xs
3233 in (getSum s, getSum c)
3334
3435triangular :: Integral a => a -> a
test/Regression/T8.hs+12−13
@@ -1,15 +1,14 @@
11module Regression.T8 (test8) where
22
3−import Control.Ether.Abbr
4−import Control.Monad.Ether
3+import Ether
54
65import qualified Control.Monad.State as T
76
87import Test.Tasty
98import Test.Tasty.QuickCheck
109
11−ethereal "Foo" "foo"
12−ethereal "Bar" "bar"
10+data Foo
11+data Bar
1312
1413testMTL1 :: T.MonadState Int m => m ()
1514testMTL1 = T.modify negate
@@ -18,25 +17,25 @@ testMTL2 :: T.MonadState Bool m => m ()
1817testMTL2 = T.modify not
1918
2019testEther
21− :: Ether '[Foo <-> Int, Bar <-> Bool] m
20+ :: (MonadState Foo Int m, MonadState Bar Bool m)
2221 => m String
2322testEther = do
24− tagAttach foo testMTL1
25− tagAttach bar testMTL2
26− a <- gets foo show
27− b <- gets bar show
23+ tagAttach @Foo testMTL1
24+ tagAttach @Bar testMTL2
25+ a <- gets @Foo show
26+ b <- gets @Bar show
2827 return (a ++ b)
2928
3029model :: Int -> Bool -> String
3130model a b = show (negate a) ++ show (not b)
3231
3332runner1 a b
34− = flip (evalState foo) a
35− . flip (evalStateT bar) b
33+ = flip (evalState @Foo) a
34+ . flip (evalStateT @Bar) b
3635
3736runner2 a b
38− = flip (evalState bar) b
39− . flip (evalStateT foo) a
37+ = flip (evalState @Bar) b
38+ . flip (evalStateT @Foo) a
4039
4140test8 :: TestTree
4241test8 = testGroup "T8: Multiple tag attachements"
test/Regression/T9.hsnew file+49
@@ -0,0 +1,49 @@
1+module Regression.T9 (test9) where
2+
3+import Ether
4+
5+import Test.Tasty
6+import Test.Tasty.QuickCheck
7+
8+data Foo
9+data Bar
10+
11+testEther1 :: MonadState Foo Int m => m String
12+testEther1 = do
13+ modify @Foo negate
14+ gets @Foo show
15+
16+testEther2 :: MonadState Bar Int m => m String
17+testEther2 = tagReplace @Foo @Bar testEther1
18+
19+testEther
20+ :: (MonadState Foo Int m, MonadState Bar Int m)
21+ => m String
22+testEther = do
23+ a <- testEther1
24+ b <- testEther2
25+ return (a ++ b)
26+
27+model :: Int -> Int -> String
28+model a b = show (negate a) ++ show (negate b)
29+
30+runner1 a b
31+ = flip (evalState @Foo) a
32+ . flip (evalStateT @Bar) b
33+
34+runner2 a b
35+ = flip (evalState @Bar) b
36+ . flip (evalStateT @Foo) a
37+
38+test9 :: TestTree
39+test9 = testGroup "T9: Tag replacement"
40+ [ testProperty "runner₁ works"
41+ $ \a b -> property
42+ $ runner1 a b testEther == model a b
43+ , testProperty "runner₂ works"
44+ $ \a b -> property
45+ $ runner2 a b testEther == model a b
46+ , testProperty "runner₁ == runner₂"
47+ $ \a b -> property
48+ $ runner1 a b testEther == runner2 a b testEther
49+ ]
test/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module TupleInstances () where
5+
6+#ifdef DISABLE_TUP_INSTANCES
7+import Ether.Internal (makeTupleInstancesHasLens)
8+makeTupleInstancesHasLens [2]
9+#endif