on master help sign in
23 files changed+335−376
since splitsnapshots
unifiedsplit
.gitignore+17−2 .travis.yml+25−18 CHANGELOG.md+5 README.md−16 bench/Bench.hs+1 bench/TupleInstances.hs+9 ether.cabal+46−16 shell.nix+22 src/Ether/Except.hs+1−15 src/Ether/Internal.hs+6−117 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+2−30 src/Ether/State.hs−56 src/Ether/TagDispatch.hs−50 src/Ether/TaggedTrans.hs+32−8 src/Ether/Writer.hs−40 stack.yaml−8 test/Regression/T1.hs+1 test/TupleInstances.hs+9
.gitignore+17−2
@@ -1,6 +1,21 @@
1−tags
1+# Cabal
22dist
33dist-newstyle
4−.stack-work
54.cabal-sandbox/
65cabal.sandbox.config
6+cabal.project.local
7+.ghc.environment*
8+
9+# Profiling
10+*.prof
11+
12+# Stack
13+.stack-work
14+
15+# Emacs
16+TAGS
17+.dir-locals.el
18+
19+# Vim
20+tags
21+*.swp
.travis.yml+25−18
@@ -1,24 +1,31 @@
1−sudo: false
1+language: nix
22
3−cache:
4− directories:
5− - $HOME/.stack/
3+os:
4+ - linux
5+ - osx
66
7−before_install:
8− - mkdir -p ~/.local/bin
9− - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
10− - export PATH=~/.local/bin:$PATH
11− - stack --version
12− - stack setup
7+env:
8+ - HC=ghc822
9+ - HC=ghc844
10+ - HC=ghc861
1311
14−install:
15− - stack install --only-dependencies --no-terminal
12+before_install:
13+ - curl https://raw.githubusercontent.com/monadfix/nix-cabal/master/nix-cabal -o nix-cabal && chmod u+x nix-cabal
14+ - travis_retry ./nix-cabal new-update
1615
1716script:
18− - stack test ether:regression --no-terminal --ghc-options -Werror
19− - stack bench ether:bench --no-terminal --ghc-options -Werror
17+ - ./nix-cabal new-test ether:regression
18+ - ./nix-cabal new-bench ether:bench
19+
20+cache:
21+ directories:
22+ - ~/.cabal
23+ - ~/.ghc
2024
21−addons:
22− apt:
23− packages:
24− - libgmp-dev
25+matrix:
26+ # broken at the moment
27+ exclude:
28+ - os: osx
29+ env: HC=ghc822
30+ - os: osx
31+ env: HC=ghc861
CHANGELOG.md+5
@@ -1,3 +1,8 @@
1+0.5.1.0
2+-------
3+
4+* Disable `HasLens` for tuples via cabal flag.
5+
160.5.0.0
27-------
38
README.md−16
@@ -2,24 +2,8 @@
22
33[![Build Status](https://img.shields.io/travis/int-index/ether.svg)](https://travis-ci.org/int-index/ether)
44[![Hackage](https://img.shields.io/hackage/v/ether.svg)](https://hackage.haskell.org/package/ether)
5−[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/int-index/ether)
65
76
87Ether is a Haskell library that extends [mtl](https://hackage.haskell.org/package/mtl)
98and [transformers](https://hackage.haskell.org/package/transformers) with tagged
109monad transformers and classes in a compatible way.
11−
12−## Installation
13−
14−You can install `ether 0.4.0.0`
15−
16−1. using Cabal, from Hackage;
17−2. using Stack, from Stackage;
18−3. using Portage, from Gentoo Haskell Overlay.
19−
20−If unsure, use [Stack](https://github.com/commercialhaskell/stack).
21−
22−## Getting Started
23−
24−To get started, read the introduction on the [homepage](https://int-index.github.io/ether/).
25−If you need help with Ether or if you have any questions about it, ask me in the Gitter chat.
bench/Bench.hs+1
@@ -8,6 +8,7 @@ import qualified Control.Monad.Reader as M
88import qualified Control.Monad.State as M
99import Criterion.Main
1010import Ether
11+import TupleInstances ()
1112
1213id' :: a -> a
1314id' = 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+46−16
@@ -1,21 +1,17 @@
1+cabal-version: 2.2
12name: ether
2−version: 0.5.0.0
3+version: 0.5.2.0
34synopsis: Monad transformers and classes
4−description:
5− Ether is a Haskell library that extends @mtl@ and @transformers@ with
6− tagged monad transformers and classes in a compatible way.
7−
8− Introduction <https://int-index.github.io/ether/>
9−
10−category: Control
11−license: BSD3
5+description: Lib
6+license: BSD-3-Clause
7+-- ^ unfortunately have to change this line due to the issue with cabal2nix
128license-file: LICENSE
9+category: Control
1310author: Vladislav Zavialov
1411maintainer: Vladislav Zavialov <vlad.z.4096@gmail.com>
1512homepage: https://int-index.github.io/ether/
1613bug-reports: https://github.com/int-index/ether/issues
1714build-type: Simple
18−cabal-version: >=1.18
1915extra-source-files: CHANGELOG.md
2016
2117source-repository head
@@ -24,6 +20,20 @@ source-repository head
2420 location: git@github.com:int-index/ether.git
2521
2622
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+
2737library
2838
2939 exposed-modules:
@@ -36,11 +46,18 @@ library
3646 Ether.TagDispatch
3747 Ether.Internal
3848
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+
3956 build-depends:
40− base >=4.9 && <4.11,
41− transformers >=0.5.4.0,
42− transformers-lift >=0.2.0.0,
43− mtl >=2.2.1,
57+ base >=4.9 && <4.13,
58+ transformers >=0.5.2.0,
59+ transformers-lift >=0.2.0.1,
60+ mtl >=2.2.2,
4461 mmorph >=1.0.4,
4562 monad-control >=1.0.0.4,
4663 transformers-base >=0.4.4,
@@ -84,10 +101,13 @@ library
84101 ghc-options:
85102 -Wall -O2
86103
104+ if flag(disable-tup-instances)
105+ cpp-options: -DDISABLE_TUP_INSTANCES
106+
87107test-suite regression
88108
89109 build-depends:
90− base >=4.9 && <4.11,
110+ base >=4.9 && <4.13,
91111 transformers >=0.4.2,
92112 mtl >=2.2.1,
93113 tasty >=0.10,
@@ -101,6 +121,7 @@ test-suite regression
101121 Regression.hs
102122
103123 other-modules:
124+ TupleInstances
104125 Regression.T1
105126 Regression.T2
106127 Regression.T3
@@ -151,11 +172,14 @@ test-suite regression
151172 ghc-options:
152173 -Wall -fno-warn-missing-signatures
153174
175+ if flag(disable-tup-instances)
176+ cpp-options: -DDISABLE_TUP_INSTANCES
177+
154178
155179benchmark bench
156180
157181 build-depends:
158− base >=4.9 && <4.11,
182+ base >=4.9 && <4.13,
159183 mtl >=2.2.1,
160184 transformers >=0.4.2,
161185 criterion >=1.1,
@@ -166,6 +190,9 @@ benchmark bench
166190 main-is:
167191 Bench.hs
168192
193+ other-modules:
194+ TupleInstances
195+
169196 type:
170197 exitcode-stdio-1.0
171198
@@ -205,3 +232,6 @@ benchmark bench
205232
206233 ghc-prof-options:
207234 -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 #-}
5050 , Monad (t m)
5151 , MonadExcept tag e m
5252 ) => MonadExcept tag e (t m) where
53−
5453 throw = Lift.lift . throw @tag
55− {-# INLINE throw #-}
56−
5754 catch = Lift.liftCatch (catch @tag)
58− {-# INLINE catch #-}
5955
6056-- | Encode type-level information for 'ExceptT'.
6157data EXCEPT
@@ -77,17 +73,14 @@ type ExceptT tag e = TaggedTrans (TAGGED EXCEPT tag) (T.ExceptT e)
7773-- | Runs an 'Except' and returns either an exception or a normal value.
7874runExcept :: forall tag e a . Except tag e a -> Either e a
7975runExcept = coerce (T.runExcept @e @a)
80−{-# INLINE runExcept #-}
8176
8277-- | Runs an 'ExceptT' and returns either an exception or a normal value.
8378runExceptT :: forall tag e m a . ExceptT tag e m a -> m (Either e a)
8479runExceptT = coerce (T.runExceptT @e @m @a)
85−{-# INLINE runExceptT #-}
8680
8781-- | Constructor for computations in the exception monad transformer.
8882exceptT :: forall tag e m a . m (Either e a) -> ExceptT tag e m a
8983exceptT = coerce (T.ExceptT @e @m @a)
90−{-# INLINE exceptT #-}
9184
9285type instance HandleSuper EXCEPT e trans = ()
9386type instance HandleConstraint EXCEPT e trans m =
@@ -95,47 +88,40 @@ type instance HandleConstraint EXCEPT e trans m =
9588
9689instance Handle EXCEPT e (T.ExceptT e) where
9790 handling r = r
98− {-# INLINE handling #-}
9991
10092instance
10193 ( Handle EXCEPT e trans
10294 , Monad m, Monad (trans m)
10395 ) => MonadExcept tag e (TaggedTrans (TAGGED EXCEPT tag) trans m)
10496 where
97+
10598 throw =
10699 handling @EXCEPT @e @trans @m $
107100 coerce (T.throwError @e @(trans m) @a) ::
108101 forall eff a . e -> TaggedTrans eff trans m a
109− {-# INLINE throw #-}
110102
111103 catch =
112104 handling @EXCEPT @e @trans @m $
113105 coerce (T.catchError @e @(trans m) @a) ::
114106 forall eff a . Catch e (TaggedTrans eff trans m) a
115− {-# INLINE catch #-}
116107
117108type MonadExcept' e = MonadExcept e e
118109
119110throw' :: forall e m a . MonadExcept' e m => e -> m a
120111throw' = throw @e
121−{-# INLINE throw' #-}
122112
123113catch' :: forall e m a . MonadExcept' e m => m a -> (e -> m a) -> m a
124114catch' = catch @e
125−{-# INLINE catch' #-}
126115
127116type Except' e = Except e e
128117
129118runExcept' :: Except' e a -> Either e a
130119runExcept' = runExcept
131−{-# INLINE runExcept' #-}
132120
133121type ExceptT' e = ExceptT e e
134122
135123exceptT' :: m (Either e a) -> ExceptT' e m a
136124exceptT' = exceptT
137−{-# INLINE exceptT' #-}
138125
139126runExceptT' :: ExceptT' e m a -> m (Either e a)
140127runExceptT' = runExceptT
141−{-# INLINE runExceptT' #-}
src/Ether/Internal.hs+6−117
@@ -16,18 +16,20 @@ module Ether.Internal
1616 , HandleSuper
1717 , HandleConstraint
1818 , Handle(..)
19+ , makeTupleInstancesHasLens
1920 ) where
2021
2122import Control.Applicative
22−import Control.Monad
2323import Data.Coerce
2424import Data.Functor.Identity
2525import Data.Kind
26−import Data.List as List
2726import Data.Tagged
28−import Data.Traversable
2927import GHC.Exts (Constraint)
30−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 ()
3133
3234data TAGGED e t
3335
@@ -55,125 +57,12 @@ class
5557 where
5658 handling :: Monad m => (HandleConstraint eff p trans m => r) -> r
5759
58−type LensLike f s t a b = (a -> f b) -> s -> f t
59−
60−type Lens s t a b = forall f. Functor f => LensLike f s t a b
61−
62−type Lens' s a = Lens s s a a
63−
6460newtype ReifiedLens s t a b = Lens (Lens s t a b)
6561
6662type ReifiedLens' s a = ReifiedLens s s a a
6763
68−class HasLens tag outer inner | tag outer -> inner where
69− lensOf :: Lens' outer inner
70−
71−instance HasLens a a a where
72− lensOf = id
73− {-# INLINE lensOf #-}
74−
7564view :: LensLike (Const a) s t a b -> s -> a
7665view l = coerce (l Const)
77−{-# INLINE view #-}
7866
7967over :: LensLike Identity s t a b -> (a -> b) -> s -> t
8068over = coerce
81−{-# INLINE over #-}
82−
83−data HList xs where
84− HNil :: HList '[]
85− HCons :: x -> HList xs -> HList (x ': xs)
86−
87−type KindOf (a :: k) = k
88−
89−type family TagsK (p :: Type) :: [Type]
90−type family Tags (p :: Type) :: HList (TagsK p)
91−
92−return []
93−
94−type instance TagsK () = '[]
95−type instance TagsK (Tagged t a) = '[KindOf t]
96−type instance TagsK (Tagged t0 a, Tagged t1 b) = '[KindOf t0, KindOf t1]
97−
98−return []
99−
100−type instance Tags () = 'HNil
101−type instance Tags (Tagged t a) = 'HCons t 'HNil
102−type instance Tags (Tagged t0 a, Tagged t1 b) = 'HCons t0 ('HCons t1 'HNil)
103−
104−do
105− let
106− tupCount = 62
107− names = [1..] >>= flip replicateM ['a'..'z']
108− varNames <- traverse TH.newName (take tupCount names)
109− fmap List.concat $
110− for (List.drop 2 (List.inits varNames)) $
111− \varNames' -> do
112− let n = List.length varNames'
113− tagsInstances <- for [() | n > 2] $ \() -> do
114− tag <- TH.newName "tag"
115− let
116− (cur:rest) = varNames'
117− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
118− ( TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur :
119− map TH.VarT rest )
120− tupTy' = foldl TH.AppT (TH.ConT (TH.tupleTypeName (n-1)))
121− (map TH.VarT rest)
122− return $
123− TH.TySynInstD ''TagsK (TH.TySynEqn [tupTy]
124− ( TH.PromotedConsT `TH.AppT` (TH.ConT ''KindOf `TH.AppT` TH.VarT tag) `TH.AppT`
125− (TH.ConT ''TagsK `TH.AppT` tupTy') ))
126− return tagsInstances
127−do
128− let
129− tupCount = 62
130− names = [1..] >>= flip replicateM ['a'..'z']
131− varNames <- traverse TH.newName (take tupCount names)
132− fmap List.concat $
133− for (List.drop 2 (List.inits varNames)) $
134− \varNames' -> do
135− let n = List.length varNames'
136− tagsInstances <- for [() | n > 2] $ \() -> do
137− tag <- TH.newName "tag"
138− let
139− (cur:rest) = varNames'
140− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
141− ( TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur :
142− map TH.VarT rest )
143− tupTy' = foldl TH.AppT (TH.ConT (TH.tupleTypeName (n-1)))
144− (map TH.VarT rest)
145− tagsInst =
146− TH.TySynInstD ''Tags (TH.TySynEqn [tupTy]
147− ( TH.PromotedT 'HCons `TH.AppT` TH.VarT tag `TH.AppT`
148− (TH.ConT ''Tags `TH.AppT` tupTy') ))
149− return tagsInst
150− hasLensInstances <- for [0..n-1] $ \k -> do
151− tag <- TH.newName "tag"
152− let
153− (prev, cur:next) = List.splitAt k varNames'
154− tupTy = foldl TH.AppT (TH.ConT (TH.tupleTypeName n))
155− ( map TH.VarT prev ++
156− [TH.ConT ''Tagged `TH.AppT` TH.VarT tag `TH.AppT` TH.VarT cur] ++
157− map TH.VarT next )
158− cur' <- TH.newName "x"
159− f <- TH.newName "f"
160− return $
161− TH.InstanceD Nothing []
162− (TH.ConT ''HasLens `TH.AppT` TH.VarT tag `TH.AppT` tupTy `TH.AppT` TH.VarT cur)
163− [ TH.FunD 'lensOf
164− [ TH.Clause
165− [TH.VarP f, TH.TupP
166− ( map TH.VarP prev ++
167− [TH.ConP 'Tagged [TH.VarP cur]] ++
168− map TH.VarP next )]
169− (TH.NormalB $
170− TH.VarE 'fmap `TH.AppE`
171− (TH.LamE [TH.VarP cur']
172− (TH.TupE
173− ( map TH.VarE prev ++
174− [TH.ConE 'Tagged `TH.AppE` TH.VarE cur'] ++
175− map TH.VarE next ))) `TH.AppE`
176− (TH.VarE f `TH.AppE` TH.VarE cur) )
177− [] ],
178− TH.PragmaD (TH.InlineP 'lensOf TH.Inline TH.FunLike TH.AllPhases) ]
179− return $ tagsInstances ++ hasLensInstances
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 #-}
7777 , MonadReader tag r m
7878 ) => MonadReader tag r (t m)
7979 where
80−
8180 ask = Lift.lift (ask @tag)
82− {-# INLINE ask #-}
83−
8481 local = Lift.liftLocal (ask @tag) (local @tag)
85− {-# INLINE local #-}
86−
8782 reader = Lift.lift . reader @tag
88− {-# INLINE reader #-}
8983
9084instance {-# OVERLAPPABLE #-}
9185 ( Monad (trans m)
@@ -98,21 +92,18 @@ instance {-# OVERLAPPABLE #-}
9892 TaggedTrans effs trans m r ->
9993 TaggedTrans (eff ': effs) trans m r)
10094 (ask @tag)
101− {-# INLINE ask #-}
10295
10396 local =
10497 (coerce :: forall a .
10598 Lift.Local r (TaggedTrans effs trans m) a ->
10699 Lift.Local r (TaggedTrans (eff ': effs) trans m) a)
107100 (local @tag)
108− {-# INLINE local #-}
109101
110102 reader =
111103 (coerce :: forall a .
112104 ((r -> a) -> TaggedTrans effs trans m a) ->
113105 ((r -> a) -> TaggedTrans (eff ': effs) trans m a))
114106 (reader @tag)
115− {-# INLINE reader #-}
116107
117108-- | Retrieves a function of the current environment.
118109asks
@@ -122,7 +113,6 @@ asks
122113 -- ^ The selector function to apply to the environment.
123114 -> m a
124115asks = reader @tag
125−{-# INLINE asks #-}
126116
127117-- | Encode type-level information for 'ReaderT'.
128118data READER
@@ -145,19 +135,16 @@ type ReaderT tag r = TaggedTrans (TAGGED READER tag) (T.ReaderT r)
145135-- | Constructor for computations in the reader monad transformer.
146136readerT :: forall tag r m a . (r -> m a) -> ReaderT tag r m a
147137readerT = coerce (T.ReaderT @r @m @a)
148−{-# INLINE readerT #-}
149138
150139-- | Runs a 'ReaderT' with the given environment
151140-- and returns the final value.
152141runReaderT :: forall tag r m a . ReaderT tag r m a -> r -> m a
153−runReaderT = coerce (T.runReaderT @r @_ @m @a)
154−{-# INLINE runReaderT #-}
142+runReaderT = coerce (T.runReaderT @r @m @a)
155143
156144-- | Runs a 'ReaderT' with the given environment
157145-- and returns the final value.
158146runReader :: forall tag r a . Reader tag r a -> r -> a
159147runReader = coerce (T.runReader @r @a)
160−{-# INLINE runReader #-}
161148
162149type instance HandleSuper READER r trans = ()
163150type instance HandleConstraint READER r trans m =
@@ -165,7 +152,6 @@ type instance HandleConstraint READER r trans m =
165152
166153instance Handle READER r (T.ReaderT r) where
167154 handling r = r
168− {-# INLINE handling #-}
169155
170156instance
171157 ( Handle READER r trans
@@ -176,19 +162,16 @@ instance
176162 ask =
177163 handling @READER @r @trans @m $
178164 coerce (T.ask @r @(trans m))
179− {-# INLINE ask #-}
180165
181166 local =
182167 handling @READER @r @trans @m $
183168 coerce (T.local @r @(trans m) @a) ::
184169 forall eff a . Local r (TaggedTrans eff trans m) a
185− {-# INLINE local #-}
186170
187171 reader =
188172 handling @READER @r @trans @m $
189173 coerce (T.reader @r @(trans m) @a) ::
190174 forall eff a . (r -> a) -> TaggedTrans eff trans m a
191− {-# INLINE reader #-}
192175
193176instance
194177 ( HasLens tag payload r
@@ -203,7 +186,6 @@ instance
203186 trans m a ->
204187 TaggedTrans eff trans m a)
205188 (T.asks (view (lensOf @tag @payload @r)))
206− {-# INLINE ask #-}
207189
208190 local f =
209191 handling @READER @payload @trans @m $
@@ -211,7 +193,6 @@ instance
211193 (trans m a -> trans m a) ->
212194 (TaggedTrans eff trans m a -> TaggedTrans eff trans m a))
213195 (T.local (over (lensOf @tag @payload @r) f))
214− {-# INLINE local #-}
215196
216197type family READERS (ts :: HList xs) :: [Type] where
217198 READERS 'HNil = '[]
@@ -222,43 +203,34 @@ type ReadersT r = TaggedTrans (READERS (Tags r)) (T.ReaderT r)
222203type Readers r = ReadersT r Identity
223204
224205runReadersT :: forall p m a . ReadersT p m a -> p -> m a
225−runReadersT = coerce (T.runReaderT @p @_ @m @a)
226−{-# INLINE runReadersT #-}
206+runReadersT = coerce (T.runReaderT @p @m @a)
227207
228208runReaders :: forall p a . Readers p a -> p -> a
229209runReaders = coerce (T.runReader @p @a)
230−{-# INLINE runReaders #-}
231210
232211type ReaderT' r = ReaderT r r
233212
234213readerT' :: (r -> m a) -> ReaderT' r m a
235214readerT' = readerT
236−{-# INLINE readerT' #-}
237215
238216runReaderT' :: ReaderT' r m a -> r -> m a
239217runReaderT' = runReaderT
240−{-# INLINE runReaderT' #-}
241218
242219type Reader' r = Reader r r
243220
244221runReader' :: Reader' r a -> r -> a
245222runReader' = runReader
246−{-# INLINE runReader' #-}
247223
248224type MonadReader' r = MonadReader r r
249225
250226local' :: forall r m a . MonadReader' r m => (r -> r) -> m a -> m a
251227local' = local @r
252−{-# INLINE local' #-}
253228
254229ask' :: forall r m . MonadReader' r m => m r
255230ask' = ask @r
256−{-# INLINE ask' #-}
257231
258232reader' :: forall r m a . MonadReader' r m => (r -> a) -> m a
259233reader' = reader @r
260−{-# INLINE reader' #-}
261234
262235asks' :: forall r m a . MonadReader' r m => (r -> a) -> m a
263236asks' = asks @r
264−{-# INLINE asks' #-}
src/Ether/State.hs−56
@@ -114,15 +114,9 @@ instance {-# OVERLAPPABLE #-}
114114 , MonadState tag s m
115115 ) => MonadState tag s (t m)
116116 where
117−
118117 get = Lift.lift (get @tag)
119− {-# INLINE get #-}
120−
121118 put = Lift.lift . put @tag
122− {-# INLINE put #-}
123−
124119 state = Lift.lift . state @tag
125− {-# INLINE state #-}
126120
127121instance {-# OVERLAPPABLE #-}
128122 ( Monad (trans m)
@@ -135,31 +129,26 @@ instance {-# OVERLAPPABLE #-}
135129 TaggedTrans effs trans m s ->
136130 TaggedTrans (eff ': effs) trans m s)
137131 (get @tag)
138− {-# INLINE get #-}
139132
140133 put =
141134 (coerce ::
142135 (s -> TaggedTrans effs trans m ()) ->
143136 (s -> TaggedTrans (eff ': effs) trans m ()))
144137 (put @tag)
145− {-# INLINE put #-}
146138
147139 state =
148140 (coerce :: forall a .
149141 ((s -> (a, s)) -> TaggedTrans effs trans m a) ->
150142 ((s -> (a, s)) -> TaggedTrans (eff ': effs) trans m a))
151143 (state @tag)
152− {-# INLINE state #-}
153144
154145-- | Modifies the state inside a state monad.
155146modify :: forall tag s m . MonadState tag s m => (s -> s) -> m ()
156147modify f = state @tag (\s -> ((), f s))
157−{-# INLINABLE modify #-}
158148
159149-- | Gets specific component of the state, using a projection function supplied.
160150gets :: forall tag s m a . MonadState tag s m => (s -> a) -> m a
161151gets f = fmap f (get @tag)
162−{-# INLINABLE gets #-}
163152
164153-- | Encode type-level information for 'StateT'.
165154data STATE
@@ -170,11 +159,9 @@ type instance HandleConstraint STATE s trans m =
170159
171160instance Handle STATE s (T.Strict.StateT s) where
172161 handling r = r
173− {-# INLINE handling #-}
174162
175163instance Handle STATE s (T.Lazy.StateT s) where
176164 handling r = r
177− {-# INLINE handling #-}
178165
179166instance
180167 ( Handle STATE s trans
@@ -185,18 +172,15 @@ instance
185172 get =
186173 handling @STATE @s @trans @m $
187174 coerce (T.get @s @(trans m))
188− {-# INLINE get #-}
189175
190176 put =
191177 handling @STATE @s @trans @m $
192178 coerce (T.put @s @(trans m))
193− {-# INLINE put #-}
194179
195180 state =
196181 handling @STATE @s @trans @m $
197182 coerce (T.state @s @(trans m) @a) ::
198183 forall eff a . (s -> (a, s)) -> TaggedTrans eff trans m a
199− {-# INLINE state #-}
200184
201185instance
202186 ( HasLens tag payload s
@@ -211,7 +195,6 @@ instance
211195 trans m a ->
212196 TaggedTrans eff trans m a)
213197 (T.gets (view (lensOf @tag @payload @s)))
214− {-# INLINE get #-}
215198
216199 put s =
217200 handling @STATE @payload @trans @m $
@@ -219,7 +202,6 @@ instance
219202 trans m a ->
220203 TaggedTrans eff trans m a)
221204 (T.modify (over (lensOf @tag @payload @s) (const s)))
222− {-# INLINE put #-}
223205
224206 state f =
225207 handling @STATE @payload @trans @m $
@@ -227,7 +209,6 @@ instance
227209 trans m a ->
228210 TaggedTrans eff trans m a)
229211 (T.state (lensOf @tag @payload @s f))
230− {-# INLINE state #-}
231212
232213-- | The parametrizable state monad.
233214--
@@ -246,43 +227,36 @@ type StateT tag s = TaggedTrans (TAGGED STATE tag) (T.Strict.StateT s)
246227-- | Constructor for computations in the state monad transformer.
247228stateT :: forall tag s m a . (s -> m (a, s)) -> StateT tag s m a
248229stateT = coerce (T.Strict.StateT @s @m @a)
249−{-# INLINE stateT #-}
250230
251231-- | Runs a 'StateT' with the given initial state
252232-- and returns both the final value and the final state.
253233runStateT :: forall tag s m a . StateT tag s m a -> s -> m (a, s)
254234runStateT = coerce (T.Strict.runStateT @s @m @a)
255−{-# INLINE runStateT #-}
256235
257236-- | Runs a 'StateT' with the given initial state
258237-- and returns the final value, discarding the final state.
259238evalStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m a
260239evalStateT = coerce (T.Strict.evalStateT @m @s @a)
261−{-# INLINE evalStateT #-}
262240
263241-- | Runs a 'StateT' with the given initial state
264242-- and returns the final state, discarding the final value.
265243execStateT :: forall tag s m a . Monad m => StateT tag s m a -> s -> m s
266244execStateT = coerce (T.Strict.execStateT @m @s @a)
267−{-# INLINE execStateT #-}
268245
269246-- | Runs a 'State' with the given initial state
270247-- and returns both the final value and the final state.
271248runState :: forall tag s a . State tag s a -> s -> (a, s)
272249runState = coerce (T.Strict.runState @s @a)
273−{-# INLINE runState #-}
274250
275251-- | Runs a 'State' with the given initial state
276252-- and returns the final value, discarding the final state.
277253evalState :: forall tag s a . State tag s a -> s -> a
278254evalState = coerce (T.Strict.evalState @s @a)
279−{-# INLINE evalState #-}
280255
281256-- | Runs a 'State' with the given initial state
282257-- and returns the final state, discarding the final value.
283258execState :: forall tag s a . State tag s a -> s -> s
284259execState = coerce (T.Strict.execState @s @a)
285−{-# INLINE execState #-}
286260
287261-- | The parametrizable state monad.
288262--
@@ -301,43 +275,36 @@ type LazyStateT tag s = TaggedTrans (TAGGED STATE tag) (T.Lazy.StateT s)
301275-- | Constructor for computations in the state monad transformer.
302276lazyStateT :: forall tag s m a . (s -> m (a, s)) -> LazyStateT tag s m a
303277lazyStateT = coerce (T.Lazy.StateT @s @m @a)
304−{-# INLINE lazyStateT #-}
305278
306279-- | Runs a 'StateT' with the given initial state
307280-- and returns both the final value and the final state.
308281runLazyStateT :: forall tag s m a . LazyStateT tag s m a -> s -> m (a, s)
309282runLazyStateT = coerce (T.Lazy.runStateT @s @m @a)
310−{-# INLINE runLazyStateT #-}
311283
312284-- | Runs a 'StateT' with the given initial state
313285-- and returns the final value, discarding the final state.
314286evalLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m a
315287evalLazyStateT = coerce (T.Lazy.evalStateT @m @s @a)
316−{-# INLINE evalLazyStateT #-}
317288
318289-- | Runs a 'StateT' with the given initial state
319290-- and returns the final state, discarding the final value.
320291execLazyStateT :: forall tag s m a . Monad m => LazyStateT tag s m a -> s -> m s
321292execLazyStateT = coerce (T.Lazy.execStateT @m @s @a)
322−{-# INLINE execLazyStateT #-}
323293
324294-- | Runs a 'State' with the given initial state
325295-- and returns both the final value and the final state.
326296runLazyState :: forall tag s a . LazyState tag s a -> s -> (a, s)
327297runLazyState = coerce (T.Lazy.runState @s @a)
328−{-# INLINE runLazyState #-}
329298
330299-- | Runs a 'State' with the given initial state
331300-- and returns the final value, discarding the final state.
332301evalLazyState :: forall tag s a . LazyState tag s a -> s -> a
333302evalLazyState = coerce (T.Lazy.evalState @s @a)
334−{-# INLINE evalLazyState #-}
335303
336304-- | Runs a 'State' with the given initial state
337305-- and returns the final state, discarding the final value.
338306execLazyState :: forall tag s a . LazyState tag s a -> s -> s
339307execLazyState = coerce (T.Lazy.execState @s @a)
340−{-# INLINE execLazyState #-}
341308
342309type family STATES (ts :: HList xs) :: [Type] where
343310 STATES 'HNil = '[]
@@ -349,97 +316,76 @@ type States s = StatesT s Identity
349316
350317runStatesT :: forall p m a . StatesT p m a -> p -> m (a, p)
351318runStatesT = coerce (T.Strict.runStateT @p @m @a)
352−{-# INLINE runStatesT #-}
353319
354320runStates :: forall p a . States p a -> p -> (a, p)
355321runStates = coerce (T.Strict.runState @p @a)
356−{-# INLINE runStates #-}
357322
358323type StateT' s = StateT s s
359324
360325stateT' :: (s -> m (a, s)) -> StateT' s m a
361326stateT' = stateT
362−{-# INLINE stateT' #-}
363327
364328runStateT' :: StateT' s m a -> s -> m (a, s)
365329runStateT' = runStateT
366−{-# INLINE runStateT' #-}
367330
368331runState' :: State' s a -> s -> (a, s)
369332runState' = runState
370−{-# INLINE runState' #-}
371333
372334evalStateT' :: Monad m => StateT' s m a -> s -> m a
373335evalStateT' = evalStateT
374−{-# INLINE evalStateT' #-}
375336
376337type State' s = State s s
377338
378339evalState' :: State' s a -> s -> a
379340evalState' = evalState
380−{-# INLINE evalState' #-}
381341
382342execStateT' :: Monad m => StateT' s m a -> s -> m s
383343execStateT' = execStateT
384−{-# INLINE execStateT' #-}
385344
386345execState' :: State' s a -> s -> s
387346execState' = execState
388−{-# INLINE execState' #-}
389347
390348type LazyStateT' s = LazyStateT s s
391349
392350lazyStateT' :: (s -> m (a, s)) -> LazyStateT' s m a
393351lazyStateT' = lazyStateT
394−{-# INLINE lazyStateT' #-}
395352
396353runLazyStateT' :: LazyStateT' s m a -> s -> m (a, s)
397354runLazyStateT' = runLazyStateT
398−{-# INLINE runLazyStateT' #-}
399355
400356runLazyState' :: LazyState' s a -> s -> (a, s)
401357runLazyState' = runLazyState
402−{-# INLINE runLazyState' #-}
403358
404359evalLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m a
405360evalLazyStateT' = evalLazyStateT
406−{-# INLINE evalLazyStateT' #-}
407361
408362type LazyState' s = LazyState s s
409363
410364evalLazyState' :: LazyState' s a -> s -> a
411365evalLazyState' = evalLazyState
412−{-# INLINE evalLazyState' #-}
413366
414367execLazyStateT' :: Monad m => LazyStateT' s m a -> s -> m s
415368execLazyStateT' = execLazyStateT
416−{-# INLINE execLazyStateT' #-}
417369
418370execLazyState' :: LazyState' s a -> s -> s
419371execLazyState' = execLazyState
420−{-# INLINE execLazyState' #-}
421372
422373type MonadState' s = MonadState s s
423374
424375get' :: forall s m . MonadState' s m => m s
425376get' = get @s
426−{-# INLINE get' #-}
427377
428378gets' :: forall s m a . MonadState' s m => (s -> a) -> m a
429379gets' = gets @s
430−{-# INLINE gets' #-}
431380
432381put' :: forall s m . MonadState' s m => s -> m ()
433382put' = put @s
434−{-# INLINE put' #-}
435383
436384state' :: forall s m a . MonadState' s m => (s -> (a, s)) -> m a
437385state' = state @s
438−{-# INLINE state' #-}
439386
440387modify' :: forall s m . MonadState' s m => (s -> s) -> m ()
441388modify' = modify @s
442−{-# INLINE modify' #-}
443389
444390-- | Encode type-level information for 'zoom'.
445391data ZOOM t z
@@ -453,7 +399,6 @@ zoom
453399 -> (forall z . Reifies z (ReifiedLens' sOuter sInner) => ZoomT tag z m a)
454400 -> m a
455401zoom l m = reify (Lens l) (\(_ :: Proxy z) -> coerce (m @z))
456−{-# INLINE zoom #-}
457402
458403instance
459404 ( MonadState tag sOuter m
@@ -468,4 +413,3 @@ instance
468413 (state @tag . l)
469414 where
470415 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
6363-- | Attach a tag to untagged transformers.
6464tagAttach :: forall tag m a . TagAttachT tag m a -> m a
6565tagAttach = coerce (runIdentityT @_ @m @a)
66−{-# INLINE tagAttach #-}
6766
6867instance {-# OVERLAPPING #-}
6968 ( MonadReader tag r m, trans ~ IdentityT
7069 ) => Mtl.MonadReader r (TaggedTrans (TAG_ATTACH tag) trans m)
7170 where
72−
7371 ask = ask @tag
74− {-# INLINE ask #-}
75−
7672 local = local @tag
77− {-# INLINE local #-}
78−
7973 reader = reader @tag
80− {-# INLINE reader #-}
8174
8275instance {-# OVERLAPPING #-}
8376 ( MonadState tag s m, trans ~ IdentityT
8477 ) => Mtl.MonadState s (TaggedTrans (TAG_ATTACH tag) trans m)
8578 where
86−
8779 get = get @tag
88− {-# INLINE get #-}
89−
9080 put = put @tag
91− {-# INLINE put #-}
92−
9381 state = state @tag
94− {-# INLINE state #-}
9582
9683instance {-# OVERLAPPING #-}
9784 ( MonadExcept tag e m, trans ~ IdentityT
9885 ) => Mtl.MonadError e (TaggedTrans (TAG_ATTACH tag) trans m)
9986 where
100−
10187 throwError = throw @tag
102− {-# INLINE throwError #-}
103−
10488 catchError = catch @tag
105− {-# INLINE catchError #-}
10689
10790instance {-# OVERLAPPING #-}
10891 ( MonadWriter tag w m, trans ~ IdentityT
10992 ) => Mtl.MonadWriter w (TaggedTrans (TAG_ATTACH tag) trans m)
11093 where
111−
11294 writer = writer @tag
113− {-# INLINE writer #-}
114−
11595 tell = tell @tag
116− {-# INLINE tell #-}
117−
11896 listen = listen @tag
119− {-# INLINE listen #-}
120−
12197 pass = pass @tag
122− {-# INLINE pass #-}
12398
12499-- | Encode type-level information for 'tagReplace'.
125100data TAG_REPLACE tOld tNew
@@ -129,60 +104,35 @@ type TagReplaceT tOld tNew = TaggedTrans (TAG_REPLACE tOld tNew) IdentityT
129104-- | Replace a tag with another tag.
130105tagReplace :: forall tOld tNew m a . TagReplaceT tOld tNew m a -> m a
131106tagReplace = coerce (runIdentityT @_ @m @a)
132−{-# INLINE tagReplace #-}
133107
134108instance
135109 ( MonadReader tNew r m, trans ~ IdentityT
136110 ) => MonadReader tOld r (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
137111 where
138−
139112 ask = ask @tNew
140− {-# INLINE ask #-}
141−
142113 local = local @tNew
143− {-# INLINE local #-}
144−
145114 reader = reader @tNew
146− {-# INLINE reader #-}
147115
148116instance
149117 ( MonadState tNew s m, trans ~ IdentityT
150118 ) => MonadState tOld s (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
151119 where
152−
153120 get = get @tNew
154− {-# INLINE get #-}
155−
156121 put = put @tNew
157− {-# INLINE put #-}
158−
159122 state = state @tNew
160− {-# INLINE state #-}
161123
162124instance
163125 ( MonadExcept tNew e m, trans ~ IdentityT
164126 ) => MonadExcept tOld e (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
165127 where
166−
167128 throw = throw @tNew
168− {-# INLINE throw #-}
169−
170129 catch = catch @tNew
171− {-# INLINE catch #-}
172130
173131instance
174132 ( MonadWriter tNew w m, trans ~ IdentityT
175133 ) => MonadWriter tOld w (TaggedTrans (TAG_REPLACE tOld tNew) trans m)
176134 where
177−
178135 writer = writer @tNew
179− {-# INLINE writer #-}
180−
181136 tell = tell @tNew
182− {-# INLINE tell #-}
183−
184137 listen = listen @tNew
185− {-# INLINE listen #-}
186−
187138 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+
15module Ether.TaggedTrans
26 ( TaggedTrans(..)
37 ) where
@@ -7,7 +11,7 @@ import Control.Monad (MonadPlus)
711import Control.Monad.Fix (MonadFix)
812import Control.Monad.Trans.Class (MonadTrans, lift)
913import Control.Monad.IO.Class (MonadIO)
10−import Control.Monad.Morph (MFunctor, MMonad)
14+import Control.Monad.Morph (MFunctor(..), MMonad(..))
1115import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask)
1216
1317import qualified Control.Monad.Base as MB
@@ -33,7 +37,7 @@ newtype TaggedTrans tag trans m a = TaggedTrans (trans m a)
3337 deriving
3438 ( Generic
3539 , Functor, Applicative, Alternative, Monad, MonadPlus
36− , MonadFix, MonadTrans, MonadIO, MFunctor, MMonad
40+ , MonadFix, MonadTrans, MonadIO
3741 , MonadThrow, MonadCatch, MonadMask )
3842
3943type Pack tag trans m a = trans m a -> TaggedTrans tag trans m a
@@ -49,7 +53,6 @@ instance
4953 (b a -> trans m a) ->
5054 (b a -> TaggedTrans tag trans m a))
5155 MB.liftBase
52− {-# INLINE liftBase #-}
5356
5457instance
5558 ( MC.MonadTransControl trans
@@ -60,11 +63,9 @@ instance
6063 liftWith = MC.defaultLiftWith
6164 (coerce :: Pack tag trans m a)
6265 (coerce :: Unpack tag trans m a)
63− {-# INLINE liftWith #-}
6466
6567 restoreT = MC.defaultRestoreT
6668 (coerce :: Pack tag trans m a)
67− {-# INLINE restoreT #-}
6869
6970type LiftBaseWith b m a = (MC.RunInBase m b -> b a) -> m a
7071
@@ -75,7 +76,6 @@ coerceLiftBaseWith ::
7576 LiftBaseWith b (TaggedTrans tag trans m) a
7677coerceLiftBaseWith lbw =
7778 unLBW (coerce (LBW lbw))
78−{-# INLINE coerceLiftBaseWith #-}
7979
8080instance
8181 ( MC.MonadBaseControl b (trans m)
@@ -84,14 +84,12 @@ instance
8484 type StM (TaggedTrans tag trans m) a = MC.StM (trans m) a
8585
8686 liftBaseWith = coerceLiftBaseWith MC.liftBaseWith
87− {-# INLINE liftBaseWith #-}
8887
8988 restoreM =
9089 (coerce :: forall a .
9190 (MC.StM (trans m) a -> trans m a) ->
9291 (MC.StM (trans m) a -> TaggedTrans tag trans m a))
9392 MC.restoreM
94− {-# INLINE restoreM #-}
9593
9694type instance Lift.StT (TaggedTrans tag trans) a = Lift.StT trans a
9795
@@ -180,3 +178,29 @@ instance
180178 where
181179 throwError = lift . Mtl.throwError
182180 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 #-}
9696 , MonadWriter tag w m
9797 , Monoid w
9898 ) => MonadWriter tag w (t m) where
99−
10099 writer = Lift.lift . writer @tag
101− {-# INLINE writer #-}
102−
103100 tell = Lift.lift . tell @tag
104− {-# INLINE tell #-}
105−
106101 listen = Lift.liftListen (listen @tag)
107− {-# INLINE listen #-}
108−
109102 pass = Lift.liftPass (pass @tag)
110− {-# INLINE pass #-}
111103
112104-- | Execute an action and add the result of applying the given function to
113105-- its accumulator to the value of the computation.
@@ -131,11 +123,9 @@ type instance HandleConstraint WRITER w trans m =
131123
132124instance Monoid w => Handle WRITER w (T.CPS.WriterT w) where
133125 handling r = r
134− {-# INLINE handling #-}
135126
136127instance Monoid w => Handle WRITER w (T.Lazy.WriterT w) where
137128 handling r = r
138− {-# INLINE handling #-}
139129
140130instance
141131 ( Handle WRITER w trans
@@ -147,24 +137,20 @@ instance
147137 handling @WRITER @w @trans @m $
148138 coerce (T.writer @w @(trans m) @a) ::
149139 forall eff a . (a, w) -> TaggedTrans eff trans m a
150− {-# INLINE writer #-}
151140
152141 tell =
153142 handling @WRITER @w @trans @m $
154143 coerce (T.tell @w @(trans m))
155− {-# INLINE tell #-}
156144
157145 listen =
158146 handling @WRITER @w @trans @m $
159147 coerce (T.listen @w @(trans m) @a) ::
160148 forall eff a . Listen w (TaggedTrans eff trans m) a
161− {-# INLINE listen #-}
162149
163150 pass =
164151 handling @WRITER @w @trans @m $
165152 coerce (T.pass @w @(trans m) @a) ::
166153 forall eff a . Pass w (TaggedTrans eff trans m) a
167− {-# INLINE pass #-}
168154
169155-- | The parametrizable writer monad.
170156--
@@ -183,31 +169,26 @@ type WriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.CPS.WriterT w)
183169-- | Constructor for computations in the writer monad transformer.
184170writerT :: forall tag w m a . (Functor m, Monoid w) => m (a, w) -> WriterT tag w m a
185171writerT = coerce (T.CPS.writerT @m @w @a)
186−{-# INLINE writerT #-}
187172
188173-- | Runs a 'WriterT' and returns both the normal value
189174-- and the final accumulator.
190175runWriterT :: forall tag w m a . Monoid w => WriterT tag w m a -> m (a, w)
191176runWriterT = coerce (T.CPS.runWriterT @w @m @a)
192−{-# INLINE runWriterT #-}
193177
194178-- | Runs a 'Writer' and returns both the normal value
195179-- and the final accumulator.
196180runWriter :: forall tag w a . Monoid w => Writer tag w a -> (a, w)
197181runWriter = coerce (T.CPS.runWriter @w @a)
198−{-# INLINE runWriter #-}
199182
200183-- | Runs a 'WriterT' and returns the final accumulator,
201184-- discarding the normal value.
202185execWriterT :: forall tag w m a . (Monad m, Monoid w) => WriterT tag w m a -> m w
203186execWriterT = coerce (T.CPS.execWriterT @m @w @a)
204−{-# INLINE execWriterT #-}
205187
206188-- | Runs a 'Writer' and returns the final accumulator,
207189-- discarding the normal value.
208190execWriter :: forall tag w a . Monoid w => Writer tag w a -> w
209191execWriter = coerce (T.CPS.execWriter @w @a)
210−{-# INLINE execWriter #-}
211192
212193-- | The parametrizable writer monad.
213194--
@@ -226,102 +207,81 @@ type LazyWriterT tag w = TaggedTrans (TAGGED WRITER tag) (T.Lazy.WriterT w)
226207-- | Constructor for computations in the writer monad transformer.
227208lazyWriterT :: forall tag w m a . m (a, w) -> LazyWriterT tag w m a
228209lazyWriterT = coerce (T.Lazy.WriterT @w @m @a)
229−{-# INLINE lazyWriterT #-}
230210
231211-- | Runs a 'WriterT' and returns both the normal value
232212-- and the final accumulator.
233213runLazyWriterT :: forall tag w m a . LazyWriterT tag w m a -> m (a, w)
234214runLazyWriterT = coerce (T.Lazy.runWriterT @w @m @a)
235−{-# INLINE runLazyWriterT #-}
236215
237216-- | Runs a 'Writer' and returns both the normal value
238217-- and the final accumulator.
239218runLazyWriter :: forall tag w a . LazyWriter tag w a -> (a, w)
240219runLazyWriter = coerce (T.Lazy.runWriter @w @a)
241−{-# INLINE runLazyWriter #-}
242220
243221-- | Runs a 'WriterT' and returns the final accumulator,
244222-- discarding the normal value.
245223execLazyWriterT :: forall tag w m a . Monad m => LazyWriterT tag w m a -> m w
246224execLazyWriterT = coerce (T.Lazy.execWriterT @m @w @a)
247−{-# INLINE execLazyWriterT #-}
248225
249226-- | Runs a 'Writer' and returns the final accumulator,
250227-- discarding the normal value.
251228execLazyWriter :: forall tag w a . LazyWriter tag w a -> w
252229execLazyWriter = coerce (T.Lazy.execWriter @w @a)
253−{-# INLINE execLazyWriter #-}
254230
255231type Writer' w = Writer w w
256232
257233runWriter' :: Monoid w => Writer' w a -> (a, w)
258234runWriter' = runWriter
259−{-# INLINE runWriter' #-}
260235
261236execWriter' :: Monoid w => Writer' w a -> w
262237execWriter' = execWriter
263−{-# INLINE execWriter' #-}
264238
265239type WriterT' w = WriterT w w
266240
267241writerT' :: (Functor m, Monoid w) => m (a, w) -> WriterT' w m a
268242writerT' = writerT
269−{-# INLINE writerT' #-}
270243
271244runWriterT' :: Monoid w => WriterT' w m a -> m (a, w)
272245runWriterT' = runWriterT
273−{-# INLINE runWriterT' #-}
274246
275247execWriterT' :: (Monad m, Monoid w) => WriterT' w m a -> m w
276248execWriterT' = execWriterT
277−{-# INLINE execWriterT' #-}
278249
279250type LazyWriter' w = LazyWriter w w
280251
281252runLazyWriter' :: LazyWriter' w a -> (a, w)
282253runLazyWriter' = runLazyWriter
283−{-# INLINE runLazyWriter' #-}
284254
285255execLazyWriter' :: LazyWriter' w a -> w
286256execLazyWriter' = execLazyWriter
287−{-# INLINE execLazyWriter' #-}
288257
289258type LazyWriterT' w = LazyWriterT w w
290259
291260lazyWriterT' :: m (a, w) -> LazyWriterT' w m a
292261lazyWriterT' = lazyWriterT
293−{-# INLINE lazyWriterT' #-}
294262
295263runLazyWriterT' :: LazyWriterT' w m a -> m (a, w)
296264runLazyWriterT' = runLazyWriterT
297−{-# INLINE runLazyWriterT' #-}
298265
299266execLazyWriterT' :: Monad m => LazyWriterT' w m a -> m w
300267execLazyWriterT' = execLazyWriterT
301−{-# INLINE execLazyWriterT' #-}
302268
303269type MonadWriter' w = MonadWriter w w
304270
305271writer' :: forall w m a . MonadWriter' w m => (a, w) -> m a
306272writer' = writer @w
307−{-# INLINE writer' #-}
308273
309274tell' :: forall w m . MonadWriter' w m => w -> m ()
310275tell' = tell @w
311−{-# INLINE tell' #-}
312276
313277listen' :: forall w m a . MonadWriter' w m => m a -> m (a, w)
314278listen' = listen @w
315−{-# INLINE listen' #-}
316279
317280pass' :: forall w m a . MonadWriter' w m => m (a, w -> w) -> m a
318281pass' = pass @w
319−{-# INLINE pass' #-}
320282
321283listens' :: forall w m a b . MonadWriter' w m => (w -> b) -> m a -> m (a, b)
322284listens' = listens @w
323−{-# INLINE listens' #-}
324285
325286censor' :: forall w m a . MonadWriter' w m => (w -> w) -> m a -> m a
326287censor' = censor @w
327−{-# INLINE censor' #-}
stack.yamldeleted−8
@@ -1,8 +0,0 @@
1−resolver: lts-8.12
2−packages: ['.']
3−
4−extra-deps:
5−- transformers-0.5.4.0
6−- transformers-lift-0.2.0.0
7−- writer-cps-transformers-0.1.1.3
8−- writer-cps-mtl-0.1.1.4
test/Regression/T1.hs+1
@@ -1,6 +1,7 @@
11module Regression.T1 (test1) where
22
33import Ether
4+import TupleInstances ()
45import Data.List (group)
56
67import 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