on master help sign in
.gitignore+17−2
since splitsnapshots
unifiedsplit
@@ -1,6 +1,21 @@
1−tags
1+# Cabal
2dist
2dist
3dist-newstyle
3dist-newstyle
4−.stack-work
5.cabal-sandbox/
4.cabal-sandbox/
6cabal.sandbox.config
5cabal.sandbox.config
6+cabal.project.local
7+.ghc.environment*
8+
9+# Profiling
10+*.prof
11+
12+# Stack
13+.stack-work
14+
15+# Emacs
16+TAGS
17+.dir-locals.el
18+
19+# Vim
20+tags
21+*.swp
.travis.yml+25−18
@@ -1,24 +1,31 @@
1−sudo: false
1+language: nix
2
2
3−cache:
3+os:
4− directories:
4+ - linux
5− - $HOME/.stack/
5+ - osx
6
6
7−before_install:
7+env:
8− - mkdir -p ~/.local/bin
8+ - HC=ghc822
9− - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
9+ - HC=ghc844
10− - export PATH=~/.local/bin:$PATH
10+ - HC=ghc861
11− - stack --version
12− - stack setup
13
11
14−install:
12+before_install:
15− - stack install --only-dependencies --no-terminal
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
16
15
17script:
16script:
18− - stack test ether:regression --no-terminal --ghc-options -Werror
17+ - ./nix-cabal new-test ether:regression
19− - stack bench ether:bench --no-terminal --ghc-options -Werror
18+ - ./nix-cabal new-bench ether:bench
19+
20+cache:
21+ directories:
22+ - ~/.cabal
23+ - ~/.ghc
20
24
21−addons:
25+matrix:
22− apt:
26+ # broken at the moment
23− packages:
27+ exclude:
24− - libgmp-dev
28+ - os: osx
29+ env: HC=ghc822
30+ - os: osx
31+ env: HC=ghc861
CHANGELOG.md+5
@@ -1,3 +1,8 @@
1+0.5.1.0
2+-------
3+
4+* Disable `HasLens` for tuples via cabal flag.
5+
10.5.0.0
60.5.0.0
2-------
7-------
3
8
README.md−16
@@ -2,24 +2,8 @@
2
2
3[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
3[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
4[![Hackage](https://img.shields.io/hackage/v/ether.svg)](https://hackage.haskell.org/package/ether)
4[![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)
6
5
7
6
8Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
7Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
9and [transformers](https://hackage.haskell.org/package/transformers) with tagged
8and [transformers](https://hackage.haskell.org/package/transformers) with tagged
10monad transformers and classes in a compatible way.
9monad transformers and classes in a compatible way.
11−
12−## Installation
13−
14−You can install `ether 0.4.0.0`
15−
16−1. using Cabal, from Hackage;
17−2. using Stack, from Stackage;
18−3. using Portage, from Gentoo Haskell Overlay.
19−
20−If unsure, use [Stack](https://github.com/commercialhaskell/stack).
21−
22−## Getting Started
23−
24−To get started, read the introduction on the [homepage](https://int-index.github.io/ether/).
25−If you need help with Ether or if you have any questions about it, ask me in the Gitter chat.
bench/Bench.hs+1
@@ -8,6 +8,7 @@ import qualified Control.Monad.Reader as M
8import qualified Control.Monad.State as M
8import qualified Control.Monad.State as M
9import Criterion.Main
9import Criterion.Main
10import Ether
10import Ether
11+import TupleInstances ()
11
12
12id' :: a -> a
13id' :: a -> a
13id' = id
14id' = id
bench/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module TupleInstances () where
5+
6+#ifdef DISABLE_TUP_INSTANCES
7+import Ether.Internal (makeTupleInstancesHasLens)
8+makeTupleInstancesHasLens [4,5,9]
9+#endif
ether.cabal+44−14
@@ -1,21 +1,17 @@
1+cabal-version: 2.2
1name: ether
2name: ether
2−version: 0.5.0.0
3+version: 0.5.2.0
3synopsis: Monad transformers and classes
4synopsis: Monad transformers and classes
4−description:
5+description: Lib
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
6+license: BSD-3-Clause
7+-- ^ unfortunately have to change this line due to the issue with cabal2nix
12license-file: LICENSE
8license-file: LICENSE
9+category: Control
13author: Vladislav Zavialov
10author: Vladislav Zavialov
14maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
11maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
15homepage: https://int-index.github.io/ether/
12homepage: https://int-index.github.io/ether/
16bug-reports: https://github.com/int-index/ether/issues
13bug-reports: https://github.com/int-index/ether/issues
17build-type: Simple
14build-type: Simple
18−cabal-version: >=1.18
19extra-source-files: CHANGELOG.md
15extra-source-files: CHANGELOG.md
20
16
21source-repository head
17source-repository head
@@ -24,6 +20,20 @@ source-repository head
24 location: git@github.com:int-index/ether.git
20 location: git@github.com:int-index/ether.git
25
21
26
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+
27library
37library
28
38
29 exposed-modules:
39 exposed-modules:
@@ -36,11 +46,18 @@ library
36 Ether.TagDispatch
46 Ether.TagDispatch
37 Ether.Internal
47 Ether.Internal
38
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+
39 build-depends:
56 build-depends:
40− base >=4.9 && <4.11,
57+ base >=4.9 && <4.13,
41 transformers >=0.5.2.0,
58 transformers >=0.5.2.0,
42 transformers-lift >=0.2.0.1,
59 transformers-lift >=0.2.0.1,
43− mtl >=2.2.1,
60+ mtl >=2.2.2,
44 mmorph >=1.0.4,
61 mmorph >=1.0.4,
45 monad-control >=1.0.0.4,
62 monad-control >=1.0.0.4,
46 transformers-base >=0.4.4,
63 transformers-base >=0.4.4,
@@ -84,10 +101,13 @@ library
84 ghc-options:
101 ghc-options:
85 -Wall -O2
102 -Wall -O2
86
103
104+ if flag(disable-tup-instances)
105+ cpp-options: -DDISABLE_TUP_INSTANCES
106+
87test-suite regression
107test-suite regression
88
108
89 build-depends:
109 build-depends:
90− base >=4.9 && <4.11,
110+ base >=4.9 && <4.13,
91 transformers >=0.4.2,
111 transformers >=0.4.2,
92 mtl >=2.2.1,
112 mtl >=2.2.1,
93 tasty >=0.10,
113 tasty >=0.10,
@@ -101,6 +121,7 @@ test-suite regression
101 Regression.hs
121 Regression.hs
102
122
103 other-modules:
123 other-modules:
124+ TupleInstances
104 Regression.T1
125 Regression.T1
105 Regression.T2
126 Regression.T2
106 Regression.T3
127 Regression.T3
@@ -151,11 +172,14 @@ test-suite regression
151 ghc-options:
172 ghc-options:
152 -Wall -fno-warn-missing-signatures
173 -Wall -fno-warn-missing-signatures
153
174
175+ if flag(disable-tup-instances)
176+ cpp-options: -DDISABLE_TUP_INSTANCES
177+
154
178
155benchmark bench
179benchmark bench
156
180
157 build-depends:
181 build-depends:
158− base >=4.9 && <4.11,
182+ base >=4.9 && <4.13,
159 mtl >=2.2.1,
183 mtl >=2.2.1,
160 transformers >=0.4.2,
184 transformers >=0.4.2,
161 criterion >=1.1,
185 criterion >=1.1,
@@ -166,6 +190,9 @@ benchmark bench
166 main-is:
190 main-is:
167 Bench.hs
191 Bench.hs
168
192
193+ other-modules:
194+ TupleInstances
195+
169 type:
196 type:
170 exitcode-stdio-1.0
197 exitcode-stdio-1.0
171
198
@@ -205,3 +232,6 @@ benchmark bench
205
232
206 ghc-prof-options:
233 ghc-prof-options:
207 -fprof-auto
234 -fprof-auto
235+
236+ if flag(disable-tup-instances)
237+ cpp-options: -DDISABLE_TUP_INSTANCES
shell.nixnew file+22
@@ -0,0 +1,22 @@
1+{ pkgs ? import <nixpkgs> {},
2+ hc ? "ghc844"
3+}:
4+
5+pkgs.stdenv.mkDerivation rec {
6+ name = "ether";
7+ buildInputs = [
8+ pkgs.haskell.compiler.${hc}
9+ pkgs.git
10+ pkgs.zlib
11+ pkgs.cabal-install
12+ pkgs.pkgconfig
13+ ];
14+ shellHook = ''
15+ export LD_LIBRARY_PATH=${pkgs.lib.makeLibraryPath buildInputs}:$LD_LIBRARY_PATH
16+ export LANG=en_US.UTF-8
17+ '';
18+ LOCALE_ARCHIVE =
19+ if pkgs.stdenv.isLinux
20+ then "${pkgs.glibcLocales}/lib/locale/locale-archive"
21+ else "";
22+}
src/Ether/Except.hs+1−15
@@ -50,12 +50,8 @@ instance {-# OVERLAPPABLE #-}
50 , Monad (t m)
50 , Monad (t m)
51 , MonadExcept tag e m
51 , MonadExcept tag e m
52 ) => MonadExcept tag e (t m) where
52 ) => MonadExcept tag e (t m) where
53−
54 throw = Lift.lift . throw @tag
53 throw = Lift.lift . throw @tag
55− {-# INLINE throw #-}
56−
57 catch = Lift.liftCatch (catch @tag)
54 catch = Lift.liftCatch (catch @tag)
58− {-# INLINE catch #-}
59
55
60-- | Encode type-level information for 'ExceptT'.
56-- | Encode type-level information for 'ExceptT'.
61data EXCEPT
57data EXCEPT
@@ -77,17 +73,14 @@ type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
77-- | Runs an 'Except' and returns either an exception or a normal value.
73-- | Runs an 'Except' and returns either an exception or a normal value.
78runExcept :: forall tag e a . Except tag e a -> Either e a
74runExcept :: forall tag e a . Except tag e a -> Either e a
79runExcept = coerce (T.runExcept @e @a)
75runExcept = coerce (T.runExcept @e @a)
80−{-# INLINE runExcept #-}
81
76
82-- | Runs an 'ExceptT' and returns either an exception or a normal value.
77-- | Runs an 'ExceptT' and returns either an exception or a normal value.
83runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
78runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
84runExceptT = coerce (T.runExceptT @e @m @a)
79runExceptT = coerce (T.runExceptT @e @m @a)
85−{-# INLINE runExceptT #-}
86
80
87-- | Constructor for computations in the exception monad transformer.
81-- | Constructor for computations in the exception monad transformer.
88exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
82exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
89exceptT = coerce (T.ExceptT @e @m @a)
83exceptT = coerce (T.ExceptT @e @m @a)
90−{-# INLINE exceptT #-}
91
84
92type instance HandleSuper EXCEPT e trans = ()
85type instance HandleSuper EXCEPT e trans = ()
93type instance HandleConstraint EXCEPT e trans m =
86type instance HandleConstraint EXCEPT e trans m =
@@ -95,47 +88,40 @@ type instance HandleConstraint EXCEPT e trans m =
95
88
96instance Handle EXCEPT e (T.ExceptT e) where
89instance Handle EXCEPT e (T.ExceptT e) where
97 handling r = r
90 handling r = r
98− {-# INLINE handling #-}
99
91
100instance
92instance
101 ( Handle EXCEPT e trans
93 ( Handle EXCEPT e trans
102 , Monad m, Monad (trans m)
94 , Monad m, Monad (trans m)
103 ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
95 ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
104 where
96 where
97+
105 throw =
98 throw =
106 handling @EXCEPT @e @trans @m $
99 handling @EXCEPT @e @trans @m $
107 coerce (T.throwError @e @(trans m) @a) ::
100 coerce (T.throwError @e @(trans m) @a) ::
108 forall eff a . e -> TaggedTrans eff trans m a
101 forall eff a . e -> TaggedTrans eff trans m a
109− {-# INLINE throw #-}
110
102
111 catch =
103 catch =
112 handling @EXCEPT @e @trans @m $
104 handling @EXCEPT @e @trans @m $
113 coerce (T.catchError @e @(trans m) @a) ::
105 coerce (T.catchError @e @(trans m) @a) ::
114 forall eff a . Catch e (TaggedTrans eff trans m) a
106 forall eff a . Catch e (TaggedTrans eff trans m) a
115− {-# INLINE catch #-}
116
107
117type MonadExcept' e = MonadExcept e e
108type MonadExcept' e = MonadExcept e e
118
109
119throw' :: forall e m a . MonadExcept' e m => e -> m a
110throw' :: forall e m a . MonadExcept' e m => e -> m a
120throw' = throw @e
111throw' = throw @e
121−{-# INLINE throw' #-}
122
112
123catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
113catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
124catch' = catch @e
114catch' = catch @e
125−{-# INLINE catch' #-}
126
115
127type Except' e = Except e e
116type Except' e = Except e e
128
117
129runExcept' :: Except' e a -> Either e a
118runExcept' :: Except' e a -> Either e a
130runExcept' = runExcept
119runExcept' = runExcept
131−{-# INLINE runExcept' #-}
132
120
133type ExceptT' e = ExceptT e e
121type ExceptT' e = ExceptT e e
134
122
135exceptT' :: m (Either e a) -> ExceptT' e m a
123exceptT' :: m (Either e a) -> ExceptT' e m a
136exceptT' = exceptT
124exceptT' = exceptT
137−{-# INLINE exceptT' #-}
138
125
139runExceptT' :: ExceptT' e m a -> m (Either e a)
126runExceptT' :: ExceptT' e m a -> m (Either e a)
140runExceptT' = runExceptT
127runExceptT' = runExceptT
141−{-# INLINE runExceptT' #-}
src/Ether/Internal.hs+6−115
@@ -16,17 +16,20 @@ module Ether.Internal
16 , HandleSuper
16 , HandleSuper
17 , HandleConstraint
17 , HandleConstraint
18 , Handle(..)
18 , Handle(..)
19+ , makeTupleInstancesHasLens
19 ) where
20 ) where
20
21
21import Control.Applicative
22import Control.Applicative
22import Data.Coerce
23import Data.Coerce
23import Data.Functor.Identity
24import Data.Functor.Identity
24import Data.Kind
25import Data.Kind
25−import Data.List as List
26import Data.Tagged
26import Data.Tagged
27−import Data.Traversable
28import GHC.Exts (Constraint)
27import GHC.Exts (Constraint)
29−import qualified Language.Haskell.TH as TH
28+
29+import Ether.Internal.HasLens
30+import Ether.Internal.Tags
31+import Ether.Internal.TH_TupleInstances (makeTupleInstancesHasLens)
32+import Ether.Internal.TupleInstances ()
30
33
31data TAGGED e t
34data TAGGED e t
32
35
@@ -54,124 +57,12 @@ class
54 where
57 where
55 handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
58 handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
56
59
57−type LensLike f s t a b = (a -> f b) -> s -> f t
58−
59−type Lens s t a b = forall f. Functor f => LensLike f s t a b
60−
61−type Lens' s a = Lens s s a a
62−
63newtype ReifiedLens s t a b = Lens (Lens s t a b)
60newtype ReifiedLens s t a b = Lens (Lens s t a b)
64
61
65type ReifiedLens' s a = ReifiedLens s s a a
62type ReifiedLens' s a = ReifiedLens s s a a
66
63
67−class HasLens tag outer inner | tag outer -> inner where
68− lensOf :: Lens' outer inner
69−
70−instance HasLens a a a where
71− lensOf = id
72− {-# INLINE lensOf #-}
73−
74−instance HasLens t (Tagged t a) a where
75− lensOf = \f -> fmap coerce . f . coerce
76−
77view :: LensLike (Const a) s t a b -> s -> a
64view :: LensLike (Const a) s t a b -> s -> a
78view l = coerce (l Const)
65view l = coerce (l Const)
79−{-# INLINE view #-}
80
66
81over :: LensLike Identity s t a b -> (a -> b) -> s -> t
67over :: LensLike Identity s t a b -> (a -> b) -> s -> t
82over = coerce
68over = coerce
83−{-# INLINE over #-}
84−
85−data HList xs where
86− HNil :: HList '[]
87− HCons :: x -> HList xs -> HList (x ': xs)
88−
89−type KindOf (a :: k) = k
90−
91−type family TagsK (p :: Type) :: [Type]
92−type family Tags (p :: Type) :: HList (TagsK p)
93−
94−return []
95−
96−type instance TagsK () = '[]
97−type instance TagsK (Tagged t a) = '[KindOf t]
98−
99−do
100− let
101− tupCount = 62
102− varName k = TH.mkName ('a' : show k)
103− tagName k = TH.mkName ('t' : show k)
104− for [2..tupCount] $ \n -> do
105− let
106− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
107− (\k -> TH.ConT ''Tagged `TH.AppT`
108− TH.VarT (tagName k) `TH.AppT`
109− TH.VarT (varName k)) <$> [0..n-1]
110− tagsList = List.foldr
111− (\a b -> TH.PromotedConsT `TH.AppT` a `TH.AppT` b)
112− TH.PromotedNilT
113− (TH.AppT (TH.ConT ''KindOf) . TH.VarT . tagName <$> [0..n-1])
114− return $
115− TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy] tagsList)
116−
117−return []
118−
119−type instance Tags () = 'HNil
120−type instance Tags (Tagged t a) = 'HCons t 'HNil
121−
122−do
123− let
124− tupCount = 62
125− varName k = TH.mkName ('a' : show k)
126− tagName k = TH.mkName ('t' : show k)
127− for [2..tupCount] $ \n -> do
128− let
129− tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
130− (\k -> TH.ConT ''Tagged `TH.AppT`
131− TH.VarT (tagName k) `TH.AppT`
132− TH.VarT (varName k)) <$> [0..n-1]
133− tagsList = List.foldr
134− (\a b -> TH.PromotedT 'HCons `TH.AppT` a `TH.AppT` b)
135− (TH.PromotedT 'HNil)
136− (TH.VarT . tagName <$> [0..n-1])
137− return $
138− TH.TySynInstD ''Tags (TH.TySynEqn [tupTy] tagsList)
139−
140−do
141− let
142− tupCount = 62
143− varName k = TH.mkName ('a' : show k)
144− fmap List.concat $
145− for [2..tupCount] $ \n ->
146− for [0..n-1] $ \k -> do
147− let
148− tag = TH.mkName "tag"
149− prev = varName <$> [0..k-1]
150− cur = varName k
151− next = varName <$> [k+1..n-1]
152− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
153− ( map TH.VarT prev ++
154− [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
155− map TH.VarT next )
156− let
157− cur' = TH.mkName "x"
158− f = TH.mkName "f"
159− return $
160− TH.InstanceD Nothing []
161− (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
162− [ TH.FunD 'lensOf
163− [ TH.Clause
164− [TH.VarP f, TH.TupP
165− ( map TH.VarP prev ++
166− [TH.ConP 'Tagged [TH.VarP cur]] ++
167− map TH.VarP next )]
168− (TH.NormalB $
169− TH.VarE 'fmap `TH.AppE`
170− (TH.LamE [TH.VarP cur']
171− (TH.TupE
172− ( map TH.VarE prev ++
173− [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
174− map TH.VarE next ))) `TH.AppE`
175− (TH.VarE f `TH.AppE` TH.VarE cur) )
176− [] ],
177− TH.PragmaD (TH.InlineP 'lensOf TH.Inline TH.FunLike TH.AllPhases) ]
src/Ether/Internal/HasLens.hsnew file+24
@@ -0,0 +1,24 @@
1+module Ether.Internal.HasLens
2+ ( LensLike
3+ , Lens
4+ , Lens'
5+ , HasLens(..)
6+ ) where
7+
8+import Data.Tagged
9+import Data.Coerce
10+
11+type LensLike f s t a b = (a -> f b) -> s -> f t
12+
13+type Lens s t a b = forall f. Functor f => LensLike f s t a b
14+
15+type Lens' s a = Lens s s a a
16+
17+class HasLens tag outer inner | tag outer -> inner where
18+ lensOf :: Lens' outer inner
19+
20+instance HasLens a a a where
21+ lensOf = id
22+
23+instance HasLens t (Tagged t a) a where
24+ lensOf = \f -> fmap coerce . f . coerce
src/Ether/Internal/TH_TupleInstances.hsnew file+79
@@ -0,0 +1,79 @@
1+module Ether.Internal.TH_TupleInstances
2+ ( makeTupleInstancesTagsK
3+ , makeTupleInstancesTags
4+ , makeTupleInstancesHasLens
5+ ) where
6+
7+import Data.Tagged
8+import Data.Traversable
9+import Data.List as List
10+import qualified Language.Haskell.TH as TH
11+
12+import Ether.Internal.HasLens
13+import Ether.Internal.Tags
14+import Ether.Internal.TH_Utils
15+
16+makeTupleInstancesTagsK :: TH.DecsQ
17+makeTupleInstancesTagsK = do
18+ for [2..tupCount] $ \n -> do
19+ let
20+ tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
21+ (\k -> TH.ConT ''Tagged `TH.AppT`
22+ TH.VarT (tagName k) `TH.AppT`
23+ TH.VarT (varName k)) <$> [0..n-1]
24+ tagsList = List.foldr
25+ (\a b -> TH.PromotedConsT `TH.AppT` a `TH.AppT` b)
26+ TH.PromotedNilT
27+ (TH.AppT (TH.ConT ''KindOf) . TH.VarT . tagName <$> [0..n-1])
28+ return $
29+ TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy] tagsList)
30+
31+makeTupleInstancesTags :: TH.DecsQ
32+makeTupleInstancesTags = do
33+ for [2..tupCount] $ \n -> do
34+ let
35+ tupTy = List.foldl' TH.AppT (TH.ConT (TH.tupleTypeName n)) $
36+ (\k -> TH.ConT ''Tagged `TH.AppT`
37+ TH.VarT (tagName k) `TH.AppT`
38+ TH.VarT (varName k)) <$> [0..n-1]
39+ tagsList = List.foldr
40+ (\a b -> TH.PromotedT 'HCons `TH.AppT` a `TH.AppT` b)
41+ (TH.PromotedT 'HNil)
42+ (TH.VarT . tagName <$> [0..n-1])
43+ return $
44+ TH.TySynInstD ''Tags (TH.TySynEqn [tupTy] tagsList)
45+
46+makeTupleInstancesHasLens :: [Int] -> TH.DecsQ
47+makeTupleInstancesHasLens range = List.concat <$> do
48+ for range $ \n ->
49+ for [0..n-1] $ \k -> do
50+ let
51+ tag = TH.mkName "tag"
52+ prev = varName <$> [0..k-1]
53+ cur = varName k
54+ next = varName <$> [k+1..n-1]
55+ tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
56+ ( map TH.VarT prev ++
57+ [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
58+ map TH.VarT next )
59+ let
60+ cur' = TH.mkName "x"
61+ f = TH.mkName "f"
62+ return $
63+ TH.InstanceD Nothing []
64+ (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
65+ [ TH.FunD 'lensOf
66+ [ TH.Clause
67+ [TH.VarP f, TH.TupP
68+ ( map TH.VarP prev ++
69+ [TH.ConP 'Tagged [TH.VarP cur]] ++
70+ map TH.VarP next )]
71+ (TH.NormalB $
72+ TH.VarE 'fmap `TH.AppE`
73+ (TH.LamE [TH.VarP cur']
74+ (TH.TupE
75+ ( map TH.VarE prev ++
76+ [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
77+ map TH.VarE next ))) `TH.AppE`
78+ (TH.VarE f `TH.AppE` TH.VarE cur) )
79+ [] ] ]
src/Ether/Internal/TH_Utils.hsnew file+14
@@ -0,0 +1,14 @@
1+module Ether.Internal.TH_Utils
2+ ( tupCount
3+ , varName
4+ , tagName
5+ ) where
6+
7+import qualified Language.Haskell.TH as TH
8+
9+tupCount :: Int
10+tupCount = 62
11+
12+varName, tagName :: Int -> TH.Name
13+varName k = TH.mkName ('a' : show k)
14+tagName k = TH.mkName ('t' : show k)
src/Ether/Internal/Tags.hsnew file+18
@@ -0,0 +1,18 @@
1+module Ether.Internal.Tags
2+ ( Tags
3+ , TagsK
4+ , HList(..)
5+ , KindOf
6+ ) where
7+
8+import Data.Kind
9+
10+data HList xs where
11+ HNil :: HList '[]
12+ HCons :: x -> HList xs -> HList (x ': xs)
13+
14+type KindOf (a :: k) = k
15+
16+type family TagsK (p :: Type) :: [Type]
17+type family Tags (p :: Type) :: HList (TagsK p)
18+
src/Ether/Internal/TupleInstances.hsnew file+24
@@ -0,0 +1,24 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module Ether.Internal.TupleInstances () where
5+
6+import Data.Tagged
7+import Ether.Internal.Tags
8+import Ether.Internal.TH_TupleInstances
9+
10+type instance TagsK () = '[]
11+type instance TagsK (Tagged t a) = '[KindOf t]
12+type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
13+
14+makeTupleInstancesTagsK
15+
16+type instance Tags () = 'HNil
17+type instance Tags (Tagged t a) = 'HCons t 'HNil
18+type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
19+
20+makeTupleInstancesTags
21+
22+#ifndef DISABLE_TUP_INSTANCES
23+makeTupleInstancesHasLens [2..62]
24+#endif
src/Ether/Reader.hs+2−30
@@ -77,15 +77,9 @@ instance {-# OVERLAPPABLE #-}
77 , MonadReader tag r m
77 , MonadReader tag r m
78 ) => MonadReader tag r (t m)
78 ) => MonadReader tag r (t m)
79 where
79 where
80−
81 ask = Lift.lift (ask @tag)
80 ask = Lift.lift (ask @tag)
82− {-# INLINE ask #-}
83−
84 local = Lift.liftLocal (ask @tag) (local @tag)
81 local = Lift.liftLocal (ask @tag) (local @tag)
85− {-# INLINE local #-}
86−
87 reader = Lift.lift . reader @tag
82 reader = Lift.lift . reader @tag
88− {-# INLINE reader #-}
89
83
90instance {-# OVERLAPPABLE #-}
84instance {-# OVERLAPPABLE #-}
91 ( Monad (trans m)
85 ( Monad (trans m)
@@ -98,21 +92,18 @@ instance {-# OVERLAPPABLE #-}
98 TaggedTrans effs trans m r ->
92 TaggedTrans effs trans m r ->
99 TaggedTrans (eff ': effs) trans m r)
93 TaggedTrans (eff ': effs) trans m r)
100 (ask @tag)
94 (ask @tag)
101− {-# INLINE ask #-}
102
95
103 local =
96 local =
104 (coerce :: forall a .
97 (coerce :: forall a .
105 Lift.Local r (TaggedTrans effs trans m) a ->
98 Lift.Local r (TaggedTrans effs trans m) a ->
106 Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
99 Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
107 (local @tag)
100 (local @tag)
108− {-# INLINE local #-}
109
101
110 reader =
102 reader =
111 (coerce :: forall a .
103 (coerce :: forall a .
112 ((r -> a) -> TaggedTrans effs trans m a) ->
104 ((r -> a) -> TaggedTrans effs trans m a) ->
113 ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
105 ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
114 (reader @tag)
106 (reader @tag)
115− {-# INLINE reader #-}
116
107
117-- | Retrieves a function of the current environment.
108-- | Retrieves a function of the current environment.
118asks
109asks
@@ -122,7 +113,6 @@ asks
122 -- ^ The selector function to apply to the environment.
113 -- ^ The selector function to apply to the environment.
123 -> m a
114 -> m a
124asks = reader @tag
115asks = reader @tag
125−{-# INLINE asks #-}
126
116
127-- | Encode type-level information for 'ReaderT'.
117-- | Encode type-level information for 'ReaderT'.
128data READER
118data READER
@@ -145,19 +135,16 @@ type ReaderT tag r = TaggedTrans (TAGGED READER tag) (T.ReaderT r)
145-- | Constructor for computations in the reader monad transformer.
135-- | Constructor for computations in the reader monad transformer.
146readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
136readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
147readerT = coerce (T.ReaderT @r @m @a)
137readerT = coerce (T.ReaderT @r @m @a)
148−{-# INLINE readerT #-}
149
138
150-- | Runs a 'ReaderT' with the given environment
139-- | Runs a 'ReaderT' with the given environment
151-- and returns the final value.
140-- and returns the final value.
152runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
141runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
153−runReaderT = coerce (T.runReaderT @r @_ @m @a)
142+runReaderT = coerce (T.runReaderT @r @m @a)
154−{-# INLINE runReaderT #-}
155
143
156-- | Runs a 'ReaderT' with the given environment
144-- | Runs a 'ReaderT' with the given environment
157-- and returns the final value.
145-- and returns the final value.
158runReader :: forall tag r a . Reader tag r a -> r -> a
146runReader :: forall tag r a . Reader tag r a -> r -> a
159runReader = coerce (T.runReader @r @a)
147runReader = coerce (T.runReader @r @a)
160−{-# INLINE runReader #-}
161
148
162type instance HandleSuper READER r trans = ()
149type instance HandleSuper READER r trans = ()
163type instance HandleConstraint READER r trans m =
150type instance HandleConstraint READER r trans m =
@@ -165,7 +152,6 @@ type instance HandleConstraint READER r trans m =
165
152
166instance Handle READER r (T.ReaderT r) where
153instance Handle READER r (T.ReaderT r) where
167 handling r = r
154 handling r = r
168− {-# INLINE handling #-}
169
155
170instance
156instance
171 ( Handle READER r trans
157 ( Handle READER r trans
@@ -176,19 +162,16 @@ instance
176 ask =
162 ask =
177 handling @READER @r @trans @m $
163 handling @READER @r @trans @m $
178 coerce (T.ask @r @(trans m))
164 coerce (T.ask @r @(trans m))
179− {-# INLINE ask #-}
180
165
181 local =
166 local =
182 handling @READER @r @trans @m $
167 handling @READER @r @trans @m $
183 coerce (T.local @r @(trans m) @a) ::
168 coerce (T.local @r @(trans m) @a) ::
184 forall eff a . Local r (TaggedTrans eff trans m) a
169 forall eff a . Local r (TaggedTrans eff trans m) a
185− {-# INLINE local #-}
186
170
187 reader =
171 reader =
188 handling @READER @r @trans @m $
172 handling @READER @r @trans @m $
189 coerce (T.reader @r @(trans m) @a) ::
173 coerce (T.reader @r @(trans m) @a) ::
190 forall eff a . (r -> a) -> TaggedTrans eff trans m a
174 forall eff a . (r -> a) -> TaggedTrans eff trans m a
191− {-# INLINE reader #-}
192
175
193instance
176instance
194 ( HasLens tag payload r
177 ( HasLens tag payload r
@@ -203,7 +186,6 @@ instance
203 trans m a ->
186 trans m a ->
204 TaggedTrans eff trans m a)
187 TaggedTrans eff trans m a)
205 (T.asks (view (lensOf @tag @payload @r)))
188 (T.asks (view (lensOf @tag @payload @r)))
206− {-# INLINE ask #-}
207
189
208 local f =
190 local f =
209 handling @READER @payload @trans @m $
191 handling @READER @payload @trans @m $
@@ -211,7 +193,6 @@ instance
211 (trans m a -> trans m a) ->
193 (trans m a -> trans m a) ->
212 (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
194 (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
213 (T.local (over (lensOf @tag @payload @r) f))
195 (T.local (over (lensOf @tag @payload @r) f))
214− {-# INLINE local #-}
215
196
216type family READERS (ts :: HList xs) :: [Type] where
197type family READERS (ts :: HList xs) :: [Type] where
217 READERS 'HNil = '[]
198 READERS 'HNil = '[]
@@ -222,43 +203,34 @@ type ReadersT r = TaggedTrans (READERS (Tags r)) (T.ReaderT r)
222type Readers r = ReadersT r Identity
203type Readers r = ReadersT r Identity
223
204
224runReadersT :: forall p m a . ReadersT p m a -> p -> m a
205runReadersT :: forall p m a . ReadersT p m a -> p -> m a
225−runReadersT = coerce (T.runReaderT @p @_ @m @a)
206+runReadersT = coerce (T.runReaderT @p @m @a)
226−{-# INLINE runReadersT #-}
227
207
228runReaders :: forall p a . Readers p a -> p -> a
208runReaders :: forall p a . Readers p a -> p -> a
229runReaders = coerce (T.runReader @p @a)
209runReaders = coerce (T.runReader @p @a)
230−{-# INLINE runReaders #-}
231
210
232type ReaderT' r = ReaderT r r
211type ReaderT' r = ReaderT r r
233
212
234readerT' :: (r -> m a) -> ReaderT' r m a
213readerT' :: (r -> m a) -> ReaderT' r m a
235readerT' = readerT
214readerT' = readerT
236−{-# INLINE readerT' #-}
237
215
238runReaderT' :: ReaderT' r m a -> r -> m a
216runReaderT' :: ReaderT' r m a -> r -> m a
239runReaderT' = runReaderT
217runReaderT' = runReaderT
240−{-# INLINE runReaderT' #-}
241
218
242type Reader' r = Reader r r
219type Reader' r = Reader r r
243
220
244runReader' :: Reader' r a -> r -> a
221runReader' :: Reader' r a -> r -> a
245runReader' = runReader
222runReader' = runReader
246−{-# INLINE runReader' #-}
247
223
248type MonadReader' r = MonadReader r r
224type MonadReader' r = MonadReader r r
249
225
250local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
226local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
251local' = local @r
227local' = local @r
252−{-# INLINE local' #-}
253
228
254ask' :: forall r m . MonadReader' r m => m r
229ask' :: forall r m . MonadReader' r m => m r
255ask' = ask @r
230ask' = ask @r
256−{-# INLINE ask' #-}
257
231
258reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
232reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
259reader' = reader @r
233reader' = reader @r
260−{-# INLINE reader' #-}
261
234
262asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
235asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
263asks' = asks @r
236asks' = asks @r
264−{-# INLINE asks' #-}
src/Ether/State.hs−56
@@ -114,15 +114,9 @@ instance {-# OVERLAPPABLE #-}
114 , MonadState tag s m
114 , MonadState tag s m
115 ) => MonadState tag s (t m)
115 ) => MonadState tag s (t m)
116 where
116 where
117−
118 get = Lift.lift (get @tag)
117 get = Lift.lift (get @tag)
119− {-# INLINE get #-}
120−
121 put = Lift.lift . put @tag
118 put = Lift.lift . put @tag
122− {-# INLINE put #-}
123−
124 state = Lift.lift . state @tag
119 state = Lift.lift . state @tag
125− {-# INLINE state #-}
126
120
127instance {-# OVERLAPPABLE #-}
121instance {-# OVERLAPPABLE #-}
128 ( Monad (trans m)
122 ( Monad (trans m)
@@ -135,31 +129,26 @@ instance {-# OVERLAPPABLE #-}
135 TaggedTrans effs trans m s ->
129 TaggedTrans effs trans m s ->
136 TaggedTrans (eff ': effs) trans m s)
130 TaggedTrans (eff ': effs) trans m s)
137 (get @tag)
131 (get @tag)
138− {-# INLINE get #-}
139
132
140 put =
133 put =
141 (coerce ::
134 (coerce ::
142 (s -> TaggedTrans effs trans m ()) ->
135 (s -> TaggedTrans effs trans m ()) ->
143 (s -> TaggedTrans (eff ': effs) trans m ()))
136 (s -> TaggedTrans (eff ': effs) trans m ()))
144 (put @tag)
137 (put @tag)
145− {-# INLINE put #-}
146
138
147 state =
139 state =
148 (coerce :: forall a .
140 (coerce :: forall a .
149 ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
141 ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
150 ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
142 ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
151 (state @tag)
143 (state @tag)
152− {-# INLINE state #-}
153
144
154-- | Modifies the state inside a state monad.
145-- | Modifies the state inside a state monad.
155modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
146modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
156modify f = state @tag (\s -> ((), f s))
147modify f = state @tag (\s -> ((), f s))
157−{-# INLINABLE modify #-}
158
148
159-- | Gets specific component of the state, using a projection function supplied.
149-- | Gets specific component of the state, using a projection function supplied.
160gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
150gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
161gets f = fmap f (get @tag)
151gets f = fmap f (get @tag)
162−{-# INLINABLE gets #-}
163
152
164-- | Encode type-level information for 'StateT'.
153-- | Encode type-level information for 'StateT'.
165data STATE
154data STATE
@@ -170,11 +159,9 @@ type instance HandleConstraint STATE s trans m =
170
159
171instance Handle STATE s (T.Strict.StateT s) where
160instance Handle STATE s (T.Strict.StateT s) where
172 handling r = r
161 handling r = r
173− {-# INLINE handling #-}
174
162
175instance Handle STATE s (T.Lazy.StateT s) where
163instance Handle STATE s (T.Lazy.StateT s) where
176 handling r = r
164 handling r = r
177− {-# INLINE handling #-}
178
165
179instance
166instance
180 ( Handle STATE s trans
167 ( Handle STATE s trans
@@ -185,18 +172,15 @@ instance
185 get =
172 get =
186 handling @STATE @s @trans @m $
173 handling @STATE @s @trans @m $
187 coerce (T.get @s @(trans m))
174 coerce (T.get @s @(trans m))
188− {-# INLINE get #-}
189
175
190 put =
176 put =
191 handling @STATE @s @trans @m $
177 handling @STATE @s @trans @m $
192 coerce (T.put @s @(trans m))
178 coerce (T.put @s @(trans m))
193− {-# INLINE put #-}
194
179
195 state =
180 state =
196 handling @STATE @s @trans @m $
181 handling @STATE @s @trans @m $
197 coerce (T.state @s @(trans m) @a) ::
182 coerce (T.state @s @(trans m) @a) ::
198 forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
183 forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
199− {-# INLINE state #-}
200
184
201instance
185instance
202 ( HasLens tag payload s
186 ( HasLens tag payload s
@@ -211,7 +195,6 @@ instance
211 trans m a ->
195 trans m a ->
212 TaggedTrans eff trans m a)
196 TaggedTrans eff trans m a)
213 (T.gets (view (lensOf @tag @payload @s)))
197 (T.gets (view (lensOf @tag @payload @s)))
214− {-# INLINE get #-}
215
198
216 put s =
199 put s =
217 handling @STATE @payload @trans @m $
200 handling @STATE @payload @trans @m $
@@ -219,7 +202,6 @@ instance
219 trans m a ->
202 trans m a ->
220 TaggedTrans eff trans m a)
203 TaggedTrans eff trans m a)
221 (T.modify (over (lensOf @tag @payload @s) (const s)))
204 (T.modify (over (lensOf @tag @payload @s) (const s)))
222− {-# INLINE put #-}
223
205
224 state f =
206 state f =
225 handling @STATE @payload @trans @m $
207 handling @STATE @payload @trans @m $
@@ -227,7 +209,6 @@ instance
227 trans m a ->
209 trans m a ->
228 TaggedTrans eff trans m a)
210 TaggedTrans eff trans m a)
229 (T.state (lensOf @tag @payload @s f))
211 (T.state (lensOf @tag @payload @s f))
230− {-# INLINE state #-}
231
212
232-- | The parametrizable state monad.
213-- | The parametrizable state monad.
233--
214--
@@ -246,43 +227,36 @@ type StateT tag s = TaggedTrans (TAGGED STATE tag) (T.Strict.StateT s)
246-- | Constructor for computations in the state monad transformer.
227-- | Constructor for computations in the state monad transformer.
247stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
228stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
248stateT = coerce (T.Strict.StateT @s @m @a)
229stateT = coerce (T.Strict.StateT @s @m @a)
249−{-# INLINE stateT #-}
250
230
251-- | Runs a 'StateT' with the given initial state
231-- | Runs a 'StateT' with the given initial state
252-- and returns both the final value and the final state.
232-- and returns both the final value and the final state.
253runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
233runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
254runStateT = coerce (T.Strict.runStateT @s @m @a)
234runStateT = coerce (T.Strict.runStateT @s @m @a)
255−{-# INLINE runStateT #-}
256
235
257-- | Runs a 'StateT' with the given initial state
236-- | Runs a 'StateT' with the given initial state
258-- and returns the final value, discarding the final state.
237-- and returns the final value, discarding the final state.
259evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
238evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
260evalStateT = coerce (T.Strict.evalStateT @m @s @a)
239evalStateT = coerce (T.Strict.evalStateT @m @s @a)
261−{-# INLINE evalStateT #-}
262
240
263-- | Runs a 'StateT' with the given initial state
241-- | Runs a 'StateT' with the given initial state
264-- and returns the final state, discarding the final value.
242-- and returns the final state, discarding the final value.
265execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
243execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
266execStateT = coerce (T.Strict.execStateT @m @s @a)
244execStateT = coerce (T.Strict.execStateT @m @s @a)
267−{-# INLINE execStateT #-}
268
245
269-- | Runs a 'State' with the given initial state
246-- | Runs a 'State' with the given initial state
270-- and returns both the final value and the final state.
247-- and returns both the final value and the final state.
271runState :: forall tag s a . State tag s a -> s -> (a, s)
248runState :: forall tag s a . State tag s a -> s -> (a, s)
272runState = coerce (T.Strict.runState @s @a)
249runState = coerce (T.Strict.runState @s @a)
273−{-# INLINE runState #-}
274
250
275-- | Runs a 'State' with the given initial state
251-- | Runs a 'State' with the given initial state
276-- and returns the final value, discarding the final state.
252-- and returns the final value, discarding the final state.
277evalState :: forall tag s a . State tag s a -> s -> a
253evalState :: forall tag s a . State tag s a -> s -> a
278evalState = coerce (T.Strict.evalState @s @a)
254evalState = coerce (T.Strict.evalState @s @a)
279−{-# INLINE evalState #-}
280
255
281-- | Runs a 'State' with the given initial state
256-- | Runs a 'State' with the given initial state
282-- and returns the final state, discarding the final value.
257-- and returns the final state, discarding the final value.
283execState :: forall tag s a . State tag s a -> s -> s
258execState :: forall tag s a . State tag s a -> s -> s
284execState = coerce (T.Strict.execState @s @a)
259execState = coerce (T.Strict.execState @s @a)
285−{-# INLINE execState #-}
286
260
287-- | The parametrizable state monad.
261-- | The parametrizable state monad.
288--
262--
@@ -301,43 +275,36 @@ type LazyStateT tag s = TaggedTrans (TAGGED STATE tag) (T.Lazy.StateT s)
301-- | Constructor for computations in the state monad transformer.
275-- | Constructor for computations in the state monad transformer.
302lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
276lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
303lazyStateT = coerce (T.Lazy.StateT @s @m @a)
277lazyStateT = coerce (T.Lazy.StateT @s @m @a)
304−{-# INLINE lazyStateT #-}
305
278
306-- | Runs a 'StateT' with the given initial state
279-- | Runs a 'StateT' with the given initial state
307-- and returns both the final value and the final state.
280-- and returns both the final value and the final state.
308runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
281runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
309runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
282runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
310−{-# INLINE runLazyStateT #-}
311
283
312-- | Runs a 'StateT' with the given initial state
284-- | Runs a 'StateT' with the given initial state
313-- and returns the final value, discarding the final state.
285-- and returns the final value, discarding the final state.
314evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
286evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
315evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
287evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
316−{-# INLINE evalLazyStateT #-}
317
288
318-- | Runs a 'StateT' with the given initial state
289-- | Runs a 'StateT' with the given initial state
319-- and returns the final state, discarding the final value.
290-- and returns the final state, discarding the final value.
320execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
291execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
321execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
292execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
322−{-# INLINE execLazyStateT #-}
323
293
324-- | Runs a 'State' with the given initial state
294-- | Runs a 'State' with the given initial state
325-- and returns both the final value and the final state.
295-- and returns both the final value and the final state.
326runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
296runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
327runLazyState = coerce (T.Lazy.runState @s @a)
297runLazyState = coerce (T.Lazy.runState @s @a)
328−{-# INLINE runLazyState #-}
329
298
330-- | Runs a 'State' with the given initial state
299-- | Runs a 'State' with the given initial state
331-- and returns the final value, discarding the final state.
300-- and returns the final value, discarding the final state.
332evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
301evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
333evalLazyState = coerce (T.Lazy.evalState @s @a)
302evalLazyState = coerce (T.Lazy.evalState @s @a)
334−{-# INLINE evalLazyState #-}
335
303
336-- | Runs a 'State' with the given initial state
304-- | Runs a 'State' with the given initial state
337-- and returns the final state, discarding the final value.
305-- and returns the final state, discarding the final value.
338execLazyState :: forall tag s a . LazyState tag s a -> s -> s
306execLazyState :: forall tag s a . LazyState tag s a -> s -> s
339execLazyState = coerce (T.Lazy.execState @s @a)
307execLazyState = coerce (T.Lazy.execState @s @a)
340−{-# INLINE execLazyState #-}
341
308
342type family STATES (ts :: HList xs) :: [Type] where
309type family STATES (ts :: HList xs) :: [Type] where
343 STATES 'HNil = '[]
310 STATES 'HNil = '[]
@@ -349,97 +316,76 @@ type States s = StatesT s Identity
349
316
350runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
317runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
351runStatesT = coerce (T.Strict.runStateT @p @m @a)
318runStatesT = coerce (T.Strict.runStateT @p @m @a)
352−{-# INLINE runStatesT #-}
353
319
354runStates :: forall p a . States p a -> p -> (a, p)
320runStates :: forall p a . States p a -> p -> (a, p)
355runStates = coerce (T.Strict.runState @p @a)
321runStates = coerce (T.Strict.runState @p @a)
356−{-# INLINE runStates #-}
357
322
358type StateT' s = StateT s s
323type StateT' s = StateT s s
359
324
360stateT' :: (s -> m (a, s)) -> StateT' s m a
325stateT' :: (s -> m (a, s)) -> StateT' s m a
361stateT' = stateT
326stateT' = stateT
362−{-# INLINE stateT' #-}
363
327
364runStateT' :: StateT' s m a -> s -> m (a, s)
328runStateT' :: StateT' s m a -> s -> m (a, s)
365runStateT' = runStateT
329runStateT' = runStateT
366−{-# INLINE runStateT' #-}
367
330
368runState' :: State' s a -> s -> (a, s)
331runState' :: State' s a -> s -> (a, s)
369runState' = runState
332runState' = runState
370−{-# INLINE runState' #-}
371
333
372evalStateT' :: Monad m => StateT' s m a -> s -> m a
334evalStateT' :: Monad m => StateT' s m a -> s -> m a
373evalStateT' = evalStateT
335evalStateT' = evalStateT
374−{-# INLINE evalStateT' #-}
375
336
376type State' s = State s s
337type State' s = State s s
377
338
378evalState' :: State' s a -> s -> a
339evalState' :: State' s a -> s -> a
379evalState' = evalState
340evalState' = evalState
380−{-# INLINE evalState' #-}
381
341
382execStateT' :: Monad m => StateT' s m a -> s -> m s
342execStateT' :: Monad m => StateT' s m a -> s -> m s
383execStateT' = execStateT
343execStateT' = execStateT
384−{-# INLINE execStateT' #-}
385
344
386execState' :: State' s a -> s -> s
345execState' :: State' s a -> s -> s
387execState' = execState
346execState' = execState
388−{-# INLINE execState' #-}
389
347
390type LazyStateT' s = LazyStateT s s
348type LazyStateT' s = LazyStateT s s
391
349
392lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
350lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
393lazyStateT' = lazyStateT
351lazyStateT' = lazyStateT
394−{-# INLINE lazyStateT' #-}
395
352
396runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
353runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
397runLazyStateT' = runLazyStateT
354runLazyStateT' = runLazyStateT
398−{-# INLINE runLazyStateT' #-}
399
355
400runLazyState' :: LazyState' s a -> s -> (a, s)
356runLazyState' :: LazyState' s a -> s -> (a, s)
401runLazyState' = runLazyState
357runLazyState' = runLazyState
402−{-# INLINE runLazyState' #-}
403
358
404evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
359evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
405evalLazyStateT' = evalLazyStateT
360evalLazyStateT' = evalLazyStateT
406−{-# INLINE evalLazyStateT' #-}
407
361
408type LazyState' s = LazyState s s
362type LazyState' s = LazyState s s
409
363
410evalLazyState' :: LazyState' s a -> s -> a
364evalLazyState' :: LazyState' s a -> s -> a
411evalLazyState' = evalLazyState
365evalLazyState' = evalLazyState
412−{-# INLINE evalLazyState' #-}
413
366
414execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
367execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
415execLazyStateT' = execLazyStateT
368execLazyStateT' = execLazyStateT
416−{-# INLINE execLazyStateT' #-}
417
369
418execLazyState' :: LazyState' s a -> s -> s
370execLazyState' :: LazyState' s a -> s -> s
419execLazyState' = execLazyState
371execLazyState' = execLazyState
420−{-# INLINE execLazyState' #-}
421
372
422type MonadState' s = MonadState s s
373type MonadState' s = MonadState s s
423
374
424get' :: forall s m . MonadState' s m => m s
375get' :: forall s m . MonadState' s m => m s
425get' = get @s
376get' = get @s
426−{-# INLINE get' #-}
427
377
428gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
378gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
429gets' = gets @s
379gets' = gets @s
430−{-# INLINE gets' #-}
431
380
432put' :: forall s m . MonadState' s m => s -> m ()
381put' :: forall s m . MonadState' s m => s -> m ()
433put' = put @s
382put' = put @s
434−{-# INLINE put' #-}
435
383
436state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
384state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
437state' = state @s
385state' = state @s
438−{-# INLINE state' #-}
439
386
440modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
387modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
441modify' = modify @s
388modify' = modify @s
442−{-# INLINE modify' #-}
443
389
444-- | Encode type-level information for 'zoom'.
390-- | Encode type-level information for 'zoom'.
445data ZOOM t z
391data ZOOM t z
@@ -453,7 +399,6 @@ zoom
453 -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
399 -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
454 -> m a
400 -> m a
455zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
401zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
456−{-# INLINE zoom #-}
457
402
458instance
403instance
459 ( MonadState tag sOuter m
404 ( MonadState tag sOuter m
@@ -468,4 +413,3 @@ instance
468 (state @tag . l)
413 (state @tag . l)
469 where
414 where
470 Lens l = reflect (Proxy :: Proxy z)
415 Lens l = reflect (Proxy :: Proxy z)
471− {-# INLINE state #-}
src/Ether/TagDispatch.hs−50
@@ -63,63 +63,38 @@ type TagAttachT t = TaggedTrans (TAG_ATTACH t) IdentityT
63-- | Attach a tag to untagged transformers.
63-- | Attach a tag to untagged transformers.
64tagAttach :: forall tag m a . TagAttachT tag m a -> m a
64tagAttach :: forall tag m a . TagAttachT tag m a -> m a
65tagAttach = coerce (runIdentityT @_ @m @a)
65tagAttach = coerce (runIdentityT @_ @m @a)
66−{-# INLINE tagAttach #-}
67
66
68instance {-# OVERLAPPING #-}
67instance {-# OVERLAPPING #-}
69 ( MonadReader tag r m, trans ~ IdentityT
68 ( MonadReader tag r m, trans ~ IdentityT
70 ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
69 ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
71 where
70 where
72−
73 ask = ask @tag
71 ask = ask @tag
74− {-# INLINE ask #-}
75−
76 local = local @tag
72 local = local @tag
77− {-# INLINE local #-}
78−
79 reader = reader @tag
73 reader = reader @tag
80− {-# INLINE reader #-}
81
74
82instance {-# OVERLAPPING #-}
75instance {-# OVERLAPPING #-}
83 ( MonadState tag s m, trans ~ IdentityT
76 ( MonadState tag s m, trans ~ IdentityT
84 ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
77 ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
85 where
78 where
86−
87 get = get @tag
79 get = get @tag
88− {-# INLINE get #-}
89−
90 put = put @tag
80 put = put @tag
91− {-# INLINE put #-}
92−
93 state = state @tag
81 state = state @tag
94− {-# INLINE state #-}
95
82
96instance {-# OVERLAPPING #-}
83instance {-# OVERLAPPING #-}
97 ( MonadExcept tag e m, trans ~ IdentityT
84 ( MonadExcept tag e m, trans ~ IdentityT
98 ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
85 ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
99 where
86 where
100−
101 throwError = throw @tag
87 throwError = throw @tag
102− {-# INLINE throwError #-}
103−
104 catchError = catch @tag
88 catchError = catch @tag
105− {-# INLINE catchError #-}
106
89
107instance {-# OVERLAPPING #-}
90instance {-# OVERLAPPING #-}
108 ( MonadWriter tag w m, trans ~ IdentityT
91 ( MonadWriter tag w m, trans ~ IdentityT
109 ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
92 ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
110 where
93 where
111−
112 writer = writer @tag
94 writer = writer @tag
113− {-# INLINE writer #-}
114−
115 tell = tell @tag
95 tell = tell @tag
116− {-# INLINE tell #-}
117−
118 listen = listen @tag
96 listen = listen @tag
119− {-# INLINE listen #-}
120−
121 pass = pass @tag
97 pass = pass @tag
122− {-# INLINE pass #-}
123
98
124-- | Encode type-level information for 'tagReplace'.
99-- | Encode type-level information for 'tagReplace'.
125data TAG_REPLACE tOld tNew
100data TAG_REPLACE tOld tNew
@@ -129,60 +104,35 @@ type TagReplaceT tOld tNew = TaggedTrans (TAG_REPLACE tOld tNew) IdentityT
129-- | Replace a tag with another tag.
104-- | Replace a tag with another tag.
130tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
105tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
131tagReplace = coerce (runIdentityT @_ @m @a)
106tagReplace = coerce (runIdentityT @_ @m @a)
132−{-# INLINE tagReplace #-}
133
107
134instance
108instance
135 ( MonadReader tNew r m, trans ~ IdentityT
109 ( MonadReader tNew r m, trans ~ IdentityT
136 ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
110 ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
137 where
111 where
138−
139 ask = ask @tNew
112 ask = ask @tNew
140− {-# INLINE ask #-}
141−
142 local = local @tNew
113 local = local @tNew
143− {-# INLINE local #-}
144−
145 reader = reader @tNew
114 reader = reader @tNew
146− {-# INLINE reader #-}
147
115
148instance
116instance
149 ( MonadState tNew s m, trans ~ IdentityT
117 ( MonadState tNew s m, trans ~ IdentityT
150 ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
118 ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
151 where
119 where
152−
153 get = get @tNew
120 get = get @tNew
154− {-# INLINE get #-}
155−
156 put = put @tNew
121 put = put @tNew
157− {-# INLINE put #-}
158−
159 state = state @tNew
122 state = state @tNew
160− {-# INLINE state #-}
161
123
162instance
124instance
163 ( MonadExcept tNew e m, trans ~ IdentityT
125 ( MonadExcept tNew e m, trans ~ IdentityT
164 ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
126 ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
165 where
127 where
166−
167 throw = throw @tNew
128 throw = throw @tNew
168− {-# INLINE throw #-}
169−
170 catch = catch @tNew
129 catch = catch @tNew
171− {-# INLINE catch #-}
172
130
173instance
131instance
174 ( MonadWriter tNew w m, trans ~ IdentityT
132 ( MonadWriter tNew w m, trans ~ IdentityT
175 ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
133 ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
176 where
134 where
177−
178 writer = writer @tNew
135 writer = writer @tNew
179− {-# INLINE writer #-}
180−
181 tell = tell @tNew
136 tell = tell @tNew
182− {-# INLINE tell #-}
183−
184 listen = listen @tNew
137 listen = listen @tNew
185− {-# INLINE listen #-}
186−
187 pass = pass @tNew
138 pass = pass @tNew
188− {-# INLINE pass #-}
src/Ether/TaggedTrans.hs+32−8
@@ -1,3 +1,7 @@
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+
1module Ether.TaggedTrans
5module Ether.TaggedTrans
2 ( TaggedTrans(..)
6 ( TaggedTrans(..)
3 ) where
7 ) where
@@ -7,7 +11,7 @@ import Control.Monad (MonadPlus)
7import Control.Monad.Fix (MonadFix)
11import Control.Monad.Fix (MonadFix)
8import Control.Monad.Trans.Class (MonadTrans, lift)
12import Control.Monad.Trans.Class (MonadTrans, lift)
9import Control.Monad.IO.Class (MonadIO)
13import Control.Monad.IO.Class (MonadIO)
10−import Control.Monad.Morph (MFunctor, MMonad)
14+import Control.Monad.Morph (MFunctor(..), MMonad(..))
11import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
15import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
12
16
13import qualified Control.Monad.Base as MB
17import qualified Control.Monad.Base as MB
@@ -33,7 +37,7 @@ newtype TaggedTrans tag trans m a = TaggedTrans (trans m a)
33 deriving
37 deriving
34 ( Generic
38 ( Generic
35 , Functor, Applicative, Alternative, Monad, MonadPlus
39 , Functor, Applicative, Alternative, Monad, MonadPlus
36− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
40+ , MonadFix, MonadTrans, MonadIO
37 , MonadThrow, MonadCatch, MonadMask )
41 , MonadThrow, MonadCatch, MonadMask )
38
42
39type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
43type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
@@ -49,7 +53,6 @@ instance
49 (b a -> trans m a) ->
53 (b a -> trans m a) ->
50 (b a -> TaggedTrans tag trans m a))
54 (b a -> TaggedTrans tag trans m a))
51 MB.liftBase
55 MB.liftBase
52− {-# INLINE liftBase #-}
53
56
54instance
57instance
55 ( MC.MonadTransControl trans
58 ( MC.MonadTransControl trans
@@ -60,11 +63,9 @@ instance
60 liftWith = MC.defaultLiftWith
63 liftWith = MC.defaultLiftWith
61 (coerce :: Pack tag trans m a)
64 (coerce :: Pack tag trans m a)
62 (coerce :: Unpack tag trans m a)
65 (coerce :: Unpack tag trans m a)
63− {-# INLINE liftWith #-}
64
66
65 restoreT = MC.defaultRestoreT
67 restoreT = MC.defaultRestoreT
66 (coerce :: Pack tag trans m a)
68 (coerce :: Pack tag trans m a)
67− {-# INLINE restoreT #-}
68
69
69type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
70type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
70
71
@@ -75,7 +76,6 @@ coerceLiftBaseWith ::
75 LiftBaseWith b (TaggedTrans tag trans m) a
76 LiftBaseWith b (TaggedTrans tag trans m) a
76coerceLiftBaseWith lbw =
77coerceLiftBaseWith lbw =
77 unLBW (coerce (LBW lbw))
78 unLBW (coerce (LBW lbw))
78−{-# INLINE coerceLiftBaseWith #-}
79
79
80instance
80instance
81 ( MC.MonadBaseControl b (trans m)
81 ( MC.MonadBaseControl b (trans m)
@@ -84,14 +84,12 @@ instance
84 type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
84 type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
85
85
86 liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
86 liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
87− {-# INLINE liftBaseWith #-}
88
87
89 restoreM =
88 restoreM =
90 (coerce :: forall a .
89 (coerce :: forall a .
91 (MC.StM (trans m) a -> trans m a) ->
90 (MC.StM (trans m) a -> trans m a) ->
92 (MC.StM (trans m) a -> TaggedTrans tag trans m a))
91 (MC.StM (trans m) a -> TaggedTrans tag trans m a))
93 MC.restoreM
92 MC.restoreM
94− {-# INLINE restoreM #-}
95
93
96type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
94type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
97
95
@@ -180,3 +178,29 @@ instance
180 where
178 where
181 throwError = lift . Mtl.throwError
179 throwError = lift . Mtl.throwError
182 catchError = Lift.liftCatch Mtl.catchError
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.hs−40
@@ -96,18 +96,10 @@ instance {-# OVERLAPPABLE #-}
96 , MonadWriter tag w m
96 , MonadWriter tag w m
97 , Monoid w
97 , Monoid w
98 ) => MonadWriter tag w (t m) where
98 ) => MonadWriter tag w (t m) where
99−
100 writer = Lift.lift . writer @tag
99 writer = Lift.lift . writer @tag
101− {-# INLINE writer #-}
102−
103 tell = Lift.lift . tell @tag
100 tell = Lift.lift . tell @tag
104− {-# INLINE tell #-}
105−
106 listen = Lift.liftListen (listen @tag)
101 listen = Lift.liftListen (listen @tag)
107− {-# INLINE listen #-}
108−
109 pass = Lift.liftPass (pass @tag)
102 pass = Lift.liftPass (pass @tag)
110− {-# INLINE pass #-}
111
103
112-- | Execute an action and add the result of applying the given function to
104-- | Execute an action and add the result of applying the given function to
113-- its accumulator to the value of the computation.
105-- its accumulator to the value of the computation.
@@ -131,11 +123,9 @@ type instance HandleConstraint WRITER w trans m =
131
123
132instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
124instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
133 handling r = r
125 handling r = r
134− {-# INLINE handling #-}
135
126
136instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
127instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
137 handling r = r
128 handling r = r
138− {-# INLINE handling #-}
139
129
140instance
130instance
141 ( Handle WRITER w trans
131 ( Handle WRITER w trans
@@ -147,24 +137,20 @@ instance
147 handling @WRITER @w @trans @m $
137 handling @WRITER @w @trans @m $
148 coerce (T.writer @w @(trans m) @a) ::
138 coerce (T.writer @w @(trans m) @a) ::
149 forall eff a . (a, w) -> TaggedTrans eff trans m a
139 forall eff a . (a, w) -> TaggedTrans eff trans m a
150− {-# INLINE writer #-}
151
140
152 tell =
141 tell =
153 handling @WRITER @w @trans @m $
142 handling @WRITER @w @trans @m $
154 coerce (T.tell @w @(trans m))
143 coerce (T.tell @w @(trans m))
155− {-# INLINE tell #-}
156
144
157 listen =
145 listen =
158 handling @WRITER @w @trans @m $
146 handling @WRITER @w @trans @m $
159 coerce (T.listen @w @(trans m) @a) ::
147 coerce (T.listen @w @(trans m) @a) ::
160 forall eff a . Listen w (TaggedTrans eff trans m) a
148 forall eff a . Listen w (TaggedTrans eff trans m) a
161− {-# INLINE listen #-}
162
149
163 pass =
150 pass =
164 handling @WRITER @w @trans @m $
151 handling @WRITER @w @trans @m $
165 coerce (T.pass @w @(trans m) @a) ::
152 coerce (T.pass @w @(trans m) @a) ::
166 forall eff a . Pass w (TaggedTrans eff trans m) a
153 forall eff a . Pass w (TaggedTrans eff trans m) a
167− {-# INLINE pass #-}
168
154
169-- | The parametrizable writer monad.
155-- | The parametrizable writer monad.
170--
156--
@@ -183,31 +169,26 @@ type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
183-- | Constructor for computations in the writer monad transformer.
169-- | Constructor for computations in the writer monad transformer.
184writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
170writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
185writerT = coerce (T.CPS.writerT @m @w @a)
171writerT = coerce (T.CPS.writerT @m @w @a)
186−{-# INLINE writerT #-}
187
172
188-- | Runs a 'WriterT' and returns both the normal value
173-- | Runs a 'WriterT' and returns both the normal value
189-- and the final accumulator.
174-- and the final accumulator.
190runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
175runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
191runWriterT = coerce (T.CPS.runWriterT @w @m @a)
176runWriterT = coerce (T.CPS.runWriterT @w @m @a)
192−{-# INLINE runWriterT #-}
193
177
194-- | Runs a 'Writer' and returns both the normal value
178-- | Runs a 'Writer' and returns both the normal value
195-- and the final accumulator.
179-- and the final accumulator.
196runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
180runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
197runWriter = coerce (T.CPS.runWriter @w @a)
181runWriter = coerce (T.CPS.runWriter @w @a)
198−{-# INLINE runWriter #-}
199
182
200-- | Runs a 'WriterT' and returns the final accumulator,
183-- | Runs a 'WriterT' and returns the final accumulator,
201-- discarding the normal value.
184-- discarding the normal value.
202execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
185execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
203execWriterT = coerce (T.CPS.execWriterT @m @w @a)
186execWriterT = coerce (T.CPS.execWriterT @m @w @a)
204−{-# INLINE execWriterT #-}
205
187
206-- | Runs a 'Writer' and returns the final accumulator,
188-- | Runs a 'Writer' and returns the final accumulator,
207-- discarding the normal value.
189-- discarding the normal value.
208execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
190execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
209execWriter = coerce (T.CPS.execWriter @w @a)
191execWriter = coerce (T.CPS.execWriter @w @a)
210−{-# INLINE execWriter #-}
211
192
212-- | The parametrizable writer monad.
193-- | The parametrizable writer monad.
213--
194--
@@ -226,102 +207,81 @@ type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
226-- | Constructor for computations in the writer monad transformer.
207-- | Constructor for computations in the writer monad transformer.
227lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
208lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
228lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
209lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
229−{-# INLINE lazyWriterT #-}
230
210
231-- | Runs a 'WriterT' and returns both the normal value
211-- | Runs a 'WriterT' and returns both the normal value
232-- and the final accumulator.
212-- and the final accumulator.
233runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
213runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
234runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
214runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
235−{-# INLINE runLazyWriterT #-}
236
215
237-- | Runs a 'Writer' and returns both the normal value
216-- | Runs a 'Writer' and returns both the normal value
238-- and the final accumulator.
217-- and the final accumulator.
239runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
218runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
240runLazyWriter = coerce (T.Lazy.runWriter @w @a)
219runLazyWriter = coerce (T.Lazy.runWriter @w @a)
241−{-# INLINE runLazyWriter #-}
242
220
243-- | Runs a 'WriterT' and returns the final accumulator,
221-- | Runs a 'WriterT' and returns the final accumulator,
244-- discarding the normal value.
222-- discarding the normal value.
245execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
223execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
246execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
224execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
247−{-# INLINE execLazyWriterT #-}
248
225
249-- | Runs a 'Writer' and returns the final accumulator,
226-- | Runs a 'Writer' and returns the final accumulator,
250-- discarding the normal value.
227-- discarding the normal value.
251execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
228execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
252execLazyWriter = coerce (T.Lazy.execWriter @w @a)
229execLazyWriter = coerce (T.Lazy.execWriter @w @a)
253−{-# INLINE execLazyWriter #-}
254
230
255type Writer' w = Writer w w
231type Writer' w = Writer w w
256
232
257runWriter' :: Monoid w => Writer' w a -> (a, w)
233runWriter' :: Monoid w => Writer' w a -> (a, w)
258runWriter' = runWriter
234runWriter' = runWriter
259−{-# INLINE runWriter' #-}
260
235
261execWriter' :: Monoid w => Writer' w a -> w
236execWriter' :: Monoid w => Writer' w a -> w
262execWriter' = execWriter
237execWriter' = execWriter
263−{-# INLINE execWriter' #-}
264
238
265type WriterT' w = WriterT w w
239type WriterT' w = WriterT w w
266
240
267writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
241writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
268writerT' = writerT
242writerT' = writerT
269−{-# INLINE writerT' #-}
270
243
271runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
244runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
272runWriterT' = runWriterT
245runWriterT' = runWriterT
273−{-# INLINE runWriterT' #-}
274
246
275execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
247execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
276execWriterT' = execWriterT
248execWriterT' = execWriterT
277−{-# INLINE execWriterT' #-}
278
249
279type LazyWriter' w = LazyWriter w w
250type LazyWriter' w = LazyWriter w w
280
251
281runLazyWriter' :: LazyWriter' w a -> (a, w)
252runLazyWriter' :: LazyWriter' w a -> (a, w)
282runLazyWriter' = runLazyWriter
253runLazyWriter' = runLazyWriter
283−{-# INLINE runLazyWriter' #-}
284
254
285execLazyWriter' :: LazyWriter' w a -> w
255execLazyWriter' :: LazyWriter' w a -> w
286execLazyWriter' = execLazyWriter
256execLazyWriter' = execLazyWriter
287−{-# INLINE execLazyWriter' #-}
288
257
289type LazyWriterT' w = LazyWriterT w w
258type LazyWriterT' w = LazyWriterT w w
290
259
291lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
260lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
292lazyWriterT' = lazyWriterT
261lazyWriterT' = lazyWriterT
293−{-# INLINE lazyWriterT' #-}
294
262
295runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
263runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
296runLazyWriterT' = runLazyWriterT
264runLazyWriterT' = runLazyWriterT
297−{-# INLINE runLazyWriterT' #-}
298
265
299execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
266execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
300execLazyWriterT' = execLazyWriterT
267execLazyWriterT' = execLazyWriterT
301−{-# INLINE execLazyWriterT' #-}
302
268
303type MonadWriter' w = MonadWriter w w
269type MonadWriter' w = MonadWriter w w
304
270
305writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
271writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
306writer' = writer @w
272writer' = writer @w
307−{-# INLINE writer' #-}
308
273
309tell' :: forall w m . MonadWriter' w m => w -> m ()
274tell' :: forall w m . MonadWriter' w m => w -> m ()
310tell' = tell @w
275tell' = tell @w
311−{-# INLINE tell' #-}
312
276
313listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
277listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
314listen' = listen @w
278listen' = listen @w
315−{-# INLINE listen' #-}
316
279
317pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
280pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
318pass' = pass @w
281pass' = pass @w
319−{-# INLINE pass' #-}
320
282
321listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
283listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
322listens' = listens @w
284listens' = listens @w
323−{-# INLINE listens' #-}
324
285
325censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
286censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
326censor' = censor @w
287censor' = censor @w
327−{-# INLINE censor' #-}
stack.yamldeleted−5
@@ -1,5 +0,0 @@
1−resolver: lts-8.13
2−packages: ['.']
3−
4−extra-deps:
5−- transformers-lift-0.2.0.1
test/Regression/T1.hs+1
@@ -1,6 +1,7 @@
1module Regression.T1 (test1) where
1module Regression.T1 (test1) where
2
2
3import Ether
3import Ether
4+import TupleInstances ()
4import Data.List (group)
5import Data.List (group)
5
6
6import Test.Tasty
7import Test.Tasty
test/TupleInstances.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# OPTIONS -fno-warn-orphans #-}
2+{-# LANGUAGE CPP #-}
3+
4+module TupleInstances () where
5+
6+#ifdef DISABLE_TUP_INSTANCES
7+import Ether.Internal (makeTupleInstancesHasLens)
8+makeTupleInstancesHasLens [2]
9+#endif