on master help sign in
Remove the Tagged machinary
d30a220Index Int
ether.cabal+1−2
@@ -24,8 +24,7 @@ source-repository head
24
24
25library
25library
26
26
27− exposed-modules: Control.Ether.Tagged
27+ exposed-modules: Control.Ether.Wrapped
28− Control.Ether.Wrapped
29 Control.Ether.Abbr
28 Control.Ether.Abbr
30 Control.Ether.Implicit.Abbr
29 Control.Ether.Implicit.Abbr
31 Control.Ether.TH
30 Control.Ether.TH
src/Control/Ether/TH.hs+1−1
@@ -26,7 +26,7 @@ proxySimple name ty = do
26-- Creates a tag and a value-level proxy for it.
26-- Creates a tag and a value-level proxy for it.
27--
27--
28-- @'ethereal' \"Foo\" \"foo\"@ generates the following code:
28-- @'ethereal' \"Foo\" \"foo\"@ generates the following code:
29−--
29+--
30-- > data Foo
30-- > data Foo
31-- > foo :: Proxy Foo
31-- > foo :: Proxy Foo
32-- > foo = Proxy
32-- > foo = Proxy
src/Control/Ether/Tagged.hsdeleted−150
@@ -1,150 +0,0 @@
1−{-# LANGUAGE TypeFamilies #-}
2−{-# LANGUAGE DataKinds #-}
3−{-# LANGUAGE PolyKinds #-}
4−{-# LANGUAGE ConstraintKinds #-}
5−{-# LANGUAGE TypeOperators #-}
6−{-# LANGUAGE FlexibleInstances #-}
7−{-# LANGUAGE UndecidableInstances #-}
8−{-# LANGUAGE MultiParamTypeClasses #-}
9−{-# LANGUAGE FunctionalDependencies #-}
10−
11−-- | Type-level machinery for tag manipulation.
12−
13−module Control.Ether.Tagged
14− ( Taggable(..)
15− , Tagged(..)
16− , Tags
17− , Inners
18− , UniqueTag
19− , UniqueTags
20− , ensureUniqueTags
21− ) where
22−
23−import Data.Proxy (Proxy)
24−import Data.Functor.Identity (Identity)
25−import Data.Monoid (First, Last)
26−import qualified Control.Monad.ST.Strict as Strict (ST)
27−import qualified Control.Monad.ST.Lazy as Lazy (ST)
28−import GHC.Conc (STM)
29−import GHC.Exts (Constraint)
30−import Control.Ether.Util (type (++), MaybeToList)
31−
32−import qualified Control.Monad.Trans.Cont as Trans
33−import qualified Control.Monad.Trans.Except as Trans
34−import qualified Control.Monad.Trans.Identity as Trans
35−import qualified Control.Monad.Trans.List as Trans
36−import qualified Control.Monad.Trans.Maybe as Trans
37−import qualified Control.Monad.Trans.Reader as Trans
38−import qualified Control.Monad.Trans.State.Lazy as Trans.Lazy
39−import qualified Control.Monad.Trans.State.Strict as Trans.Strict
40−import qualified Control.Monad.Trans.Writer.Lazy as Trans.Lazy
41−import qualified Control.Monad.Trans.Writer.Strict as Trans.Strict
42−
43−-- |
44−-- The main purpose of the 'UniqueTag' class is to provide clear error
45−-- messages when the tag uniqueness property is violated. You should never
46−-- write instances for it unless you know what you're doing.
47−class UniqueTag a
48−
49−type family IsUnique (x :: k) (as :: [k]) :: Constraint where
50− IsUnique x (x ': as) = (UniqueTag x, IsUnique x as)
51− IsUnique x (a ': as) = IsUnique x as
52− IsUnique x '[] = ()
53−
54−type family Unique (as :: [k]) :: Constraint where
55− Unique '[] = ()
56− Unique (a ': as) = (IsUnique a as, Unique as)
57−
58−-- |
59−-- The 'UniqueTags` constraint placed on a type variable representing a
60−-- monad transformer stack ensures that every tag in the stack appears
61−-- only once.
62−type family UniqueTags (m :: * -> *) :: Constraint where
63− UniqueTags m = Unique (Tags m)
64−
65−-- |
66−-- Type-restricted version of 'id' that adds a 'UniqueTags' constraint to
67−-- the provided monadic value.
68−ensureUniqueTags :: UniqueTags m => m a -> m a
69−ensureUniqueTags = id
70−
71−type family ListMapTag (as :: [* -> *]) :: [*] where
72− ListMapTag '[] = '[]
73− ListMapTag (a ': as) = MaybeToList (Tag a) ++ ListMapTag as
74−
75−-- | The 'Taggable' class defines the type families to manage tags in monad
76−-- transformer stacks. Its kind is restricted to @* -> *@ to prevent incorrect
77−-- instances.
78−class Taggable (m :: * -> *) where
79−
80− -- | The 'Tag' type family equals @Nothing@ for most types, but for tagged
81− -- monad transformers it equals @Just tag@.
82− type Tag m :: Maybe k
83− type instance Tag m = 'Nothing
84−
85− -- | The 'Inner' type family equals @Nothing@ for most types, but for
86− -- monad transformers with inner monad @m@ it equals @Just m@.
87− type Inner m :: Maybe (* -> *)
88− type instance Inner m = 'Nothing
89−
90−type family Inners' m where
91− Inners' 'Nothing = '[]
92− Inners' ('Just n) = n ': Inners n
93−
94−-- | The 'Inners' type function recursively applies 'Inner' and returns the
95−-- results in a type-level list.
96−type Inners m = Inners' (Inner m)
97−
98−instance Taggable IO
99−instance Taggable Identity
100−
101−instance Taggable Maybe
102−instance Taggable Last
103−instance Taggable First
104−instance Taggable ((->) r)
105−instance Taggable STM
106−instance Taggable (Either e)
107−instance Taggable Proxy
108−instance Taggable (Strict.ST s)
109−instance Taggable (Lazy.ST s)
110−
111−instance Taggable (Trans.ContT r m) where
112− type Inner (Trans.ContT r m) = 'Just m
113−
114−instance Taggable (Trans.ExceptT e m) where
115− type Inner (Trans.ExceptT e m) = 'Just m
116−
117−instance Taggable (Trans.IdentityT m) where
118− type Inner (Trans.IdentityT m) = 'Just m
119−
120−instance Taggable (Trans.ListT m) where
121− type Inner (Trans.ListT m) = 'Just m
122−
123−instance Taggable (Trans.MaybeT m) where
124− type Inner (Trans.MaybeT m) = 'Just m
125−
126−instance Taggable (Trans.ReaderT r m) where
127− type Inner (Trans.ReaderT r m) = 'Just m
128−
129−instance Taggable (Trans.Lazy.StateT s m) where
130− type Inner (Trans.Lazy.StateT s m) = 'Just m
131−
132−instance Taggable (Trans.Strict.StateT s m) where
133− type Inner (Trans.Strict.StateT s m) = 'Just m
134−
135−instance Taggable (Trans.Lazy.WriterT w m) where
136− type Inner (Trans.Lazy.WriterT w m) = 'Just m
137−
138−instance Taggable (Trans.Strict.WriterT w m) where
139− type Inner (Trans.Strict.WriterT w m) = 'Just m
140−
141−-- | The 'Tags' type function returns a type-level list of all tags in
142−-- a monad transformer stack. Requires 'Taggable' instances.
143−type Tags (m :: * -> *) = MaybeToList (Tag m) ++ ListMapTag (Inners m)
144−
145−-- | The 'Tagged' type class establishes a relationship between a tagged
146−-- monad transformer and its untagged counterpart.
147−class (Taggable m, Tag m ~ 'Just tag) => Tagged m tag | m -> tag where
148− type Untagged m :: * -> *
149− tagged :: proxy tag -> Untagged m a -> m a
150− untagged :: proxy tag -> m a -> Untagged m a
src/Control/Ether/Util.hs+2−2
@@ -27,10 +27,10 @@ type family MaybeToList (mt :: Maybe k) :: [k] where
27
27
28#if __GLASGOW_HASKELL__ < 710
28#if __GLASGOW_HASKELL__ < 710
29fmap :: Monad f => (a -> b) -> f a -> f b
29fmap :: Monad f => (a -> b) -> f a -> f b
30−fmap = Control.Monad.liftM
30+fmap = Control.Monad.liftM
31#else
31#else
32fmap :: Functor f => (a -> b) -> f a -> f b
32fmap :: Functor f => (a -> b) -> f a -> f b
33−fmap = Prelude.fmap
33+fmap = Prelude.fmap
34#endif
34#endif
35
35
36{-# INLINE fmap #-}
36{-# INLINE fmap #-}
src/Control/Monad/Trans/Ether/Except.hs+4−8
@@ -34,7 +34,6 @@ import Control.Monad.Fix (MonadFix)
34import Control.Monad.Trans.Class (MonadTrans, lift)
34import Control.Monad.Trans.Class (MonadTrans, lift)
35import Control.Monad.IO.Class (MonadIO)
35import Control.Monad.IO.Class (MonadIO)
36import Control.Monad.Morph (MFunctor, MMonad)
36import Control.Monad.Morph (MFunctor, MMonad)
37−import Control.Ether.Tagged (Taggable(..), Tagged(..))
38import GHC.Generics (Generic)
37import GHC.Generics (Generic)
39import Data.Coerce (coerce)
38import Data.Coerce (coerce)
40
39
@@ -116,14 +115,11 @@ instance Lift.LiftCallCC (ExceptT tag e) where
116 liftCallCC = Lift.defaultLiftCallCC pack unpack
115 liftCallCC = Lift.defaultLiftCallCC pack unpack
117 liftCallCC' = Lift.defaultLiftCallCC pack unpack
116 liftCallCC' = Lift.defaultLiftCallCC pack unpack
118
117
119−instance Taggable (ExceptT tag e m) where
118+tagged :: proxy tag -> Trans.ExceptT e m a -> ExceptT tag e m a
120− type Tag (ExceptT tag e m) = 'Just tag
119+tagged _ = pack
121− type Inner (ExceptT tag e m) = 'Just m
122
120
123−instance Tagged (ExceptT tag e m) tag where
124− type Untagged (ExceptT tag e m) = Trans.ExceptT e m
121+untagged :: proxy tag -> ExceptT tag e m a -> Trans.ExceptT e m a
125− tagged _ = pack
126− untagged _ = unpack
122+untagged _ = unpack
127
123
128-- | Constructor for computations in the exception monad transformer.
124-- | Constructor for computations in the exception monad transformer.
129exceptT :: proxy tag -> m (Either e a) -> ExceptT tag e m a
125exceptT :: proxy tag -> m (Either e a) -> ExceptT tag e m a
src/Control/Monad/Trans/Ether/Reader.hs+4−8
@@ -34,7 +34,6 @@ import Control.Monad.Fix (MonadFix)
34import Control.Monad.Trans.Class (MonadTrans, lift)
34import Control.Monad.Trans.Class (MonadTrans, lift)
35import Control.Monad.IO.Class (MonadIO)
35import Control.Monad.IO.Class (MonadIO)
36import Control.Monad.Morph (MFunctor, MMonad)
36import Control.Monad.Morph (MFunctor, MMonad)
37−import Control.Ether.Tagged (Taggable(..), Tagged(..))
38import GHC.Generics (Generic)
37import GHC.Generics (Generic)
39import Data.Coerce (coerce)
38import Data.Coerce (coerce)
40
39
@@ -112,14 +111,11 @@ instance Lift.LiftCallCC (ReaderT tag r) where
112 liftCallCC = Lift.defaultLiftCallCC pack unpack
111 liftCallCC = Lift.defaultLiftCallCC pack unpack
113 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
112 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
114
113
115−instance Taggable (ReaderT tag r m) where
114+tagged :: proxy tag -> Trans.ReaderT r m a -> ReaderT tag r m a
116− type Tag (ReaderT tag r m) = 'Just tag
115+tagged _ = pack
117− type Inner (ReaderT tag r m) = 'Just m
118
116
119−instance Tagged (ReaderT tag r m) tag where
120− type Untagged (ReaderT tag r m) = Trans.ReaderT r m
117+untagged :: proxy tag -> ReaderT tag r m a -> Trans.ReaderT r m a
121− tagged _ = pack
122− untagged _ = unpack
118+untagged _ = unpack
123
119
124-- | Constructor for computations in the reader monad transformer.
120-- | Constructor for computations in the reader monad transformer.
125readerT :: proxy tag -> (r -> m a) -> ReaderT tag r m a
121readerT :: proxy tag -> (r -> m a) -> ReaderT tag r m a
src/Control/Monad/Trans/Ether/State/Lazy.hs+4−8
@@ -38,7 +38,6 @@ import Control.Monad.Fix (MonadFix)
38import Control.Monad.Trans.Class (MonadTrans, lift)
38import Control.Monad.Trans.Class (MonadTrans, lift)
39import Control.Monad.IO.Class (MonadIO)
39import Control.Monad.IO.Class (MonadIO)
40import Control.Monad.Morph (MFunctor)
40import Control.Monad.Morph (MFunctor)
41−import Control.Ether.Tagged (Taggable(..), Tagged(..))
42import GHC.Generics (Generic)
41import GHC.Generics (Generic)
43import Data.Coerce (coerce)
42import Data.Coerce (coerce)
44
43
@@ -116,14 +115,11 @@ instance Lift.LiftCallCC (StateT tag s) where
116 liftCallCC = Lift.defaultLiftCallCC pack unpack
115 liftCallCC = Lift.defaultLiftCallCC pack unpack
117 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
116 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
118
117
119−instance Taggable (StateT tag s m) where
118+tagged :: proxy tag -> Trans.StateT s m a -> StateT tag s m a
120− type Tag (StateT tag s m) = 'Just tag
119+tagged _ = pack
121− type Inner (StateT tag s m) = 'Just m
122
120
123−instance Tagged (StateT tag s m) tag where
124− type Untagged (StateT tag s m) = Trans.StateT s m
121+untagged :: proxy tag -> StateT tag s m a -> Trans.StateT s m a
125− tagged _ = pack
126− untagged _ = unpack
122+untagged _ = unpack
127
123
128-- | Constructor for computations in the state monad transformer.
124-- | Constructor for computations in the state monad transformer.
129stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
125stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
src/Control/Monad/Trans/Ether/State/Strict.hs+4−8
@@ -38,7 +38,6 @@ import Control.Monad.Fix (MonadFix)
38import Control.Monad.Trans.Class (MonadTrans, lift)
38import Control.Monad.Trans.Class (MonadTrans, lift)
39import Control.Monad.IO.Class (MonadIO)
39import Control.Monad.IO.Class (MonadIO)
40import Control.Monad.Morph (MFunctor)
40import Control.Monad.Morph (MFunctor)
41−import Control.Ether.Tagged (Taggable(..), Tagged(..))
42import GHC.Generics (Generic)
41import GHC.Generics (Generic)
43import Data.Coerce (coerce)
42import Data.Coerce (coerce)
44
43
@@ -116,14 +115,11 @@ instance Lift.LiftCallCC (StateT tag s) where
116 liftCallCC = Lift.defaultLiftCallCC pack unpack
115 liftCallCC = Lift.defaultLiftCallCC pack unpack
117 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
116 liftCallCC' = Lift.defaultLiftCallCC' pack unpack
118
117
119−instance Taggable (StateT tag s m) where
118+tagged :: proxy tag -> Trans.StateT s m a -> StateT tag s m a
120− type Tag (StateT tag s m) = 'Just tag
119+tagged _ = pack
121− type Inner (StateT tag s m) = 'Just m
122
120
123−instance Tagged (StateT tag s m) tag where
124− type Untagged (StateT tag s m) = Trans.StateT s m
121+untagged :: proxy tag -> StateT tag s m a -> Trans.StateT s m a
125− tagged _ = pack
126− untagged _ = unpack
122+untagged _ = unpack
127
123
128-- | Constructor for computations in the state monad transformer.
124-- | Constructor for computations in the state monad transformer.
129stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
125stateT :: proxy tag -> (s -> m (a, s)) -> StateT tag s m a
src/Control/Monad/Trans/Ether/Writer.hs+4−8
@@ -42,7 +42,6 @@ import Control.Monad.Fix (MonadFix)
42import Control.Monad.Trans.Class (MonadTrans, lift)
42import Control.Monad.Trans.Class (MonadTrans, lift)
43import Control.Monad.IO.Class (MonadIO)
43import Control.Monad.IO.Class (MonadIO)
44import Control.Monad.Morph (MFunctor, MMonad)
44import Control.Monad.Morph (MFunctor, MMonad)
45−import Control.Ether.Tagged (Taggable(..), Tagged(..))
46import GHC.Generics (Generic)
45import GHC.Generics (Generic)
47import Data.Coerce (coerce)
46import Data.Coerce (coerce)
48
47
@@ -119,14 +118,11 @@ instance Monoid w => Lift.LiftCallCC (WriterT tag w) where
119 liftCallCC = Lift.defaultLiftCallCC pack unpack
118 liftCallCC = Lift.defaultLiftCallCC pack unpack
120 liftCallCC' = Lift.defaultLiftCallCC pack unpack
119 liftCallCC' = Lift.defaultLiftCallCC pack unpack
121
120
122−instance Taggable (WriterT tag w m) where
121+tagged :: proxy tag -> Trans.WriterT w m a -> WriterT tag w m a
123− type Tag (WriterT tag w m) = 'Just tag
122+tagged _ = pack
124− type Inner (WriterT tag w m) = 'Just m
125
123
126−instance Tagged (WriterT tag w m) tag where
127− type Untagged (WriterT tag w m) = Trans.WriterT w m
124+untagged :: proxy tag -> WriterT tag w m a -> Trans.WriterT w m a
128− tagged _ = pack
129− untagged _ = unpack
125+untagged _ = unpack
130
126
131-- | Constructor for computations in the writer monad transformer.
127-- | Constructor for computations in the writer monad transformer.
132writerT :: proxy tag -> m (a, w) -> WriterT tag w m a
128writerT :: proxy tag -> m (a, w) -> WriterT tag w m a
test/Regression.hs+18−20
@@ -11,7 +11,6 @@ module Main where
11
11
12import Data.Monoid
12import Data.Monoid
13import Control.Monad
13import Control.Monad
14−import Control.Ether.Tagged
15import Control.Ether.TH
14import Control.Ether.TH
16import Control.Ether.Wrapped
15import Control.Ether.Wrapped
17
16
@@ -101,24 +100,23 @@ wrapCore' = do
101wrapCore'' :: Int -> (Int, Int)
100wrapCore'' :: Int -> (Int, Int)
102wrapCore'' a = runReader r1 (runStateT s1 (runReaderT s1 wrapCore' a) a) (-1)
101wrapCore'' a = runReader r1 (runStateT s1 (runReaderT s1 wrapCore' a) a) (-1)
103
102
104−-- Should not compile with `ensureUniqueTags`
103+nonUniqueTagsCore :: IO ()
105−uniqueTagsCore :: IO ()
104+nonUniqueTagsCore
106−uniqueTagsCore = flip (runReaderT r1) (1 :: Int)
105+ = flip (runReaderT r1) (1 :: Int)
107− . flip (runReaderT r1) (True :: Bool)
106+ . flip (runReaderT r1) (True :: Bool)
108− . flip (runReaderT r1) (2 :: Int)
107+ . flip (runReaderT r1) (2 :: Int)
109− . flip (runReaderT r1) (3 :: Integer)
108+ . flip (runReaderT r1) (3 :: Integer)
110− {- . ensureUniqueTags -}
111− $ do
109+ $ do
112− a :: Integer <- ask r1
110+ a :: Integer <- ask r1
113− b :: Int <- ask r1
111+ b :: Int <- ask r1
114− c :: Bool <- ask r1
112+ c :: Bool <- ask r1
115− T.liftIO $ do
113+ T.liftIO $ do
116− print a
114+ print a
117− print b
115+ print b
118− print c
116+ print c
119−
117+
120−stateCore :: (Ether '[S1 <-> Int, R1 --> Int] m, UniqueTags m) => m ()
118+stateCore :: Ether '[S1 <-> Int, R1 --> Int] m => m ()
121−stateCore = ensureUniqueTags $ do
119+stateCore = do
122 a <- ask r1
120 a <- ask r1
123 n <- get s1
121 n <- get s1
124 put s1 (n * a)
122 put s1 (n * a)
@@ -212,7 +210,7 @@ wrapStateBad2 = do
212 T.get
210 T.get
213
211
214wrapStateBad2Core :: Int -> Int
212wrapStateBad2Core :: Int -> Int
215−wrapStateBad2Core = evalState foo (ensureUniqueTags $ ethered foo wrapStateBad2)
213+wrapStateBad2Core = evalState foo (ethered foo wrapStateBad2)
216
214
217wrapReaderCore :: Int -> Int
215wrapReaderCore :: Int -> Int
218wrapReaderCore = runReader foo (ethered foo (liftM2 (+) T.ask (ask foo)))
216wrapReaderCore = runReader foo (ethered foo (liftM2 (+) T.ask (ask foo)))