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

No changes to the content.

LICENSE → ether-flatten/LICENSErenamed

The content is the same.

Setup.hs → ether-flatten/Setup.hsrenamed

The content is the same.

ether-flatten/ether-flatten.cabalnew file+44
@@ -0,0 +1,44 @@
1+name: ether-flatten
2+version: 0.1.0.0
3+synopsis: Flatten nested monad transformers
4+description:
5+ Flatten nested monad transformers to gain performance.
6+
7+category: Control
8+license: BSD3
9+license-file: LICENSE
10+author: Vladislav Zavialov
11+maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
12+homepage: https://int-index.github.io/ether/
13+bug-reports: https://github.com/int-index/ether/issues
14+build-type: Simple
15+cabal-version: >=1.18
16+extra-source-files: CHANGELOG.md
17+
18+source-repository head
19+
20+ type: git
21+ location: git@github.com:int-index/ether.git
22+
23+
24+library
25+
26+ exposed-modules: Control.Monad.Ether.Reader.Flatten
27+ , Control.Monad.Ether.State.Flatten
28+ build-depends: base >=4.9 && <4.11
29+ , ether >=0.5 && <0.6
30+ , mtl >=2.2.1
31+ , transformers >=0.4.2
32+ , transformers-lift >=0.1.0.1
33+ , ghc-prim >=0.3
34+ , lens >=4.14
35+ , deepseq >= 1.4
36+
37+ default-language: Haskell2010
38+ default-extensions: PolyKinds
39+ ScopedTypeVariables
40+ FunctionalDependencies
41+ TypeApplications
42+
43+ hs-source-dirs: src
44+ ghc-options: -Wall -O2
ether-flatten/src/Control/Monad/Ether/Reader/Flatten.hsnew file+39
@@ -0,0 +1,39 @@
1+{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE TypeSynonymInstances #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+{-# LANGUAGE AllowAmbiguousTypes #-}
10+{-# LANGUAGE TypeInType #-}
11+{-# LANGUAGE ConstraintKinds #-}
12+
13+module Control.Monad.Ether.Reader.Flatten
14+ ( runReader
15+ , runReaderT
16+ ) where
17+
18+import Control.Ether.Optic
19+import Control.Lens
20+import Control.Monad.Ether.Handle
21+import Control.Monad.Ether.Reader (READER)
22+import qualified Control.Monad.Reader as T
23+import Control.Monad.Trans.Ether.Handler
24+import Data.Coerce
25+import Data.Kind
26+
27+type family READERS (ts :: HList xs) :: [Type] where
28+ READERS 'HNil = '[]
29+ READERS ('HCons t ts) = TAGGED READER t ': READERS ts
30+
31+type ReaderT r = Handler (READERS (Tags r)) (T.ReaderT r)
32+
33+type Reader r = ReaderT r Identity
34+
35+runReaderT :: forall p m a . ReaderT p m a -> p -> m a
36+runReaderT = coerce (T.runReaderT @p @_ @m @a)
37+
38+runReader :: forall p a . Reader p a -> p -> a
39+runReader = coerce (T.runReader @p @a)
ether-flatten/src/Control/Monad/Ether/State/Flatten.hsnew file+38
@@ -0,0 +1,38 @@
1+{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE TypeSynonymInstances #-}
3+{-# LANGUAGE DataKinds #-}
4+{-# LANGUAGE TypeOperators #-}
5+{-# LANGUAGE UndecidableInstances #-}
6+{-# LANGUAGE FlexibleInstances #-}
7+{-# LANGUAGE GADTs #-}
8+{-# LANGUAGE TypeFamilies #-}
9+{-# LANGUAGE AllowAmbiguousTypes #-}
10+{-# LANGUAGE TypeInType #-}
11+
12+module Control.Monad.Ether.State.Flatten
13+ ( runState
14+ , runStateT
15+ ) where
16+
17+import Control.Ether.Optic
18+import Control.Lens
19+import Control.Monad.Ether.Handle
20+import Control.Monad.Ether.State (STATE)
21+import qualified Control.Monad.State as T
22+import Control.Monad.Trans.Ether.Handler
23+import Data.Coerce
24+import Data.Kind
25+
26+type family STATES (ts :: HList xs) :: [Type] where
27+ STATES 'HNil = '[]
28+ STATES ('HCons t ts) = TAGGED STATE t ': STATES ts
29+
30+type StateT s = Handler (STATES (Tags s)) (T.StateT s)
31+
32+type State s = StateT s Identity
33+
34+runStateT :: forall p m a . StateT p m a -> p -> m (a, p)
35+runStateT = coerce (T.runStateT @p @m @a)
36+
37+runState :: forall p a . State p a -> p -> (a, p)
38+runState = coerce (T.runState @p @a)
ether-suite/Setup.hsnew file+2
@@ -0,0 +1,2 @@
1+import Distribution.Simple
2+main = defaultMain
bench/Bench.hs → ether-suite/bench/Bench.hsrenamed+74−63
@@ -1,14 +1,25 @@
11{-# OPTIONS -fno-warn-partial-type-signatures #-}
22
3+{-# LANGUAGE TypeApplications #-}
4+{-# LANGUAGE FlexibleInstances #-}
5+{-# LANGUAGE FunctionalDependencies #-}
6+{-# LANGUAGE FlexibleContexts #-}
7+{-# LANGUAGE DataKinds #-}
8+{-# LANGUAGE TypeOperators #-}
9+{-# LANGUAGE PartialTypeSignatures #-}
10+
311module Main (main) where
412
5−import Control.DeepSeq
6−import qualified Control.Lens as L
13+import Criterion.Main
714import qualified Control.Monad.Reader as M
815import qualified Control.Monad.State as M
9−import Criterion.Main
10−import Ether
11−import TupleInstances ()
16+import qualified Control.Monad.Ether.Reader as E
17+import qualified Control.Monad.Ether.State as E
18+import qualified Control.Monad.Ether.Reader.Flatten as E.F
19+import qualified Control.Monad.Ether.State.Flatten as E.F
20+import qualified Control.Lens as L
21+import Control.Ether.Optic
22+import Control.DeepSeq
1223
1324id' :: a -> a
1425id' = id
@@ -68,80 +79,80 @@ run_stateCombinerMTL_flat_9
6879 M.runState stateCombinerMTL_flat_9 (a9, a8, a7, a6, a5, a4, a3, a2, a1)
6980
7081readerCombinerEther_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 )
82+ :: ( E.MonadReader 1 Int m
83+ , E.MonadReader 2 Int m
84+ , E.MonadReader 3 Int m
85+ , E.MonadReader 4 Int m
86+ , E.MonadReader 5 Int m
87+ , E.MonadReader 6 Int m
88+ , E.MonadReader 7 Int m
89+ , E.MonadReader 8 Int m
90+ , E.MonadReader 9 Int m )
8091 => m ()
8192readerCombinerEther_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 ]
93+ [ E.ask @1
94+ , E.ask @2
95+ , E.ask @3
96+ , E.ask @4
97+ , E.ask @5
98+ , E.ask @6
99+ , E.ask @7
100+ , E.ask @8
101+ , E.ask @9 ]
91102{-# NOINLINE readerCombinerEther_sep_9 #-}
92103
93104stateCombinerEther_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 )
105+ :: ( E.MonadState 1 Int m
106+ , E.MonadState 2 Int m
107+ , E.MonadState 3 Int m
108+ , E.MonadState 4 Int m
109+ , E.MonadState 5 Int m
110+ , E.MonadState 6 Int m
111+ , E.MonadState 7 Int m
112+ , E.MonadState 8 Int m
113+ , E.MonadState 9 Int m )
103114 => m ()
104115stateCombinerEther_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'
116+ E.modify @1 id'
117+ E.modify @2 id'
118+ E.modify @3 id'
119+ E.modify @4 id'
120+ E.modify @5 id'
121+ E.modify @6 id'
122+ E.modify @7 id'
123+ E.modify @8 id'
124+ E.modify @9 id'
114125 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 ]
126+ [ E.get @1
127+ , E.get @2
128+ , E.get @3
129+ , E.get @4
130+ , E.get @5
131+ , E.get @6
132+ , E.get @7
133+ , E.get @8
134+ , E.get @9 ]
124135{-# NOINLINE stateCombinerEther_sep_9 #-}
125136
126137run_readerCombinerEther_nested_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
127138run_readerCombinerEther_nested_9
128139 (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
140+ = flip (E.runReader @9) a1
141+ . flip (E.runReaderT @8) a2
142+ . flip (E.runReaderT @7) a3
143+ . flip (E.runReaderT @6) a4
144+ . flip (E.runReaderT @5) a5
145+ . flip (E.runReaderT @4) a6
146+ . flip (E.runReaderT @3) a7
147+ . flip (E.runReaderT @2) a8
148+ . flip (E.runReaderT @1) a9
138149 $ readerCombinerEther_sep_9
139150
140151run_readerCombinerEther_flatten_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
141152run_readerCombinerEther_flatten_9
142153 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
143154 =
144− runReaders
155+ E.F.runReader
145156 readerCombinerEther_sep_9
146157 ( Tagged @1 a9,
147158 Tagged @2 a8,
@@ -156,12 +167,12 @@ run_readerCombinerEther_flatten_9
156167run_readerCombinerEther_flattenhalf_9 :: (Int, Int, Int, Int, Int, Int, Int, Int, Int) -> ()
157168run_readerCombinerEther_flattenhalf_9
158169 (a1, a2, a3, a4, a5, a6, a7, a8, a9) =
159− flip runReaders
170+ flip E.F.runReader
160171 ( Tagged @1 a9,
161172 Tagged @2 a8,
162173 Tagged @3 a7,
163174 Tagged @4 a6 ) .
164− flip runReadersT
175+ flip E.F.runReaderT
165176 ( Tagged @5 a5,
166177 Tagged @6 a4,
167178 Tagged @7 a3,
@@ -175,7 +186,7 @@ run_stateCombinerEther_flatten_9 ::
175186run_stateCombinerEther_flatten_9
176187 (a1, a2, a3, a4, a5, a6, a7, a8, a9)
177188 =
178− runStates
189+ E.F.runState
179190 stateCombinerEther_sep_9
180191 ( Tagged @1 a9,
181192 Tagged @2 a8,
ether-suite/ether-suite.cabalnew file+71
@@ -0,0 +1,71 @@
1+name: ether-suite
2+version: 0.1.0.0
3+build-type: Simple
4+cabal-version: >=1.18
5+
6+library
7+ -- Dummy section.
8+ default-language: Haskell2010
9+
10+test-suite regression
11+
12+ build-depends: base >=4.9 && <4.11
13+ , transformers >=0.4.2
14+ , mtl >=2.2.1
15+ , tasty >=0.10
16+ , tasty-quickcheck >=0.8
17+ , QuickCheck >=2.8
18+ , ghc-prim >=0.3
19+ , lens >=4.14
20+ , ether
21+ , ether-zoom
22+
23+ main-is: Regression.hs
24+ other-modules: Regression.T1
25+ Regression.T2
26+ Regression.T3
27+ Regression.T4
28+ Regression.T5
29+ Regression.T6
30+ Regression.T7
31+ Regression.T8
32+ Regression.T9
33+ Regression.T10
34+ Regression.T11
35+ Regression.T12
36+
37+ type: exitcode-stdio-1.0
38+ hs-source-dirs: test
39+ default-language: Haskell2010
40+ default-extensions: ConstraintKinds
41+ DataKinds
42+ EmptyDataDecls
43+ FlexibleContexts
44+ GeneralizedNewtypeDeriving
45+ LambdaCase
46+ PolyKinds
47+ ScopedTypeVariables
48+ TypeApplications
49+ TypeFamilies
50+ TypeOperators
51+ ghc-options: -Wall -fno-warn-missing-signatures
52+
53+
54+benchmark bench
55+
56+ build-depends: base >=4.9 && <4.11
57+ , mtl >=2.2.1
58+ , transformers >=0.4.2
59+ , criterion >=1.1
60+ , deepseq >=1.4
61+ , lens >=4.14
62+ , ether
63+ , ether-flatten
64+
65+ main-is: Bench.hs
66+
67+ type: exitcode-stdio-1.0
68+ hs-source-dirs: bench
69+ default-language: Haskell2010
70+ ghc-options: -Wall -O2
71+ ghc-prof-options: -fprof-auto
test/Regression.hs → ether-suite/test/Regression.hsrenamed

The content is the same.

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

No changes to the content.

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