effet 0.2.0.0 → 0.3.0.0
raw patch · 11 files changed
+391/−228 lines, 11 filesdep ~template-haskellPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: template-haskell
API changes (from Hackage documentation)
- Control.Effect.Embed: class Monad m => Embed n m
- Control.Effect.Embed: instance Control.Effect.Embed.Embed t m => Control.Effect.Embed.Embed n (Control.Effect.Embed.Transformation n t m)
- Control.Effect.Embed: instance Control.Effect.Machinery.Via.Find (Control.Effect.Embed.Embed n) effs t m => Control.Effect.Embed.Embed n (Control.Effect.Machinery.Via.EachVia (other : effs) t m)
- Control.Effect.Embed: instance Control.Effect.Machinery.Via.Handle (Control.Effect.Embed.Embed n) t m => Control.Effect.Embed.Embed n (Control.Effect.Machinery.Via.EachVia (Control.Effect.Embed.Embed n : effs) t m)
- Control.Effect.Embed: instance Control.Effect.Machinery.Via.Lift (Control.Effect.Embed.Embed n) t m => Control.Effect.Embed.Embed n (Control.Effect.Machinery.Via.EachVia '[] t m)
- Control.Effect.Embed: instance GHC.Base.Monad m => Control.Effect.Embed.Embed m m
- Control.Effect.Machinery.Default: Default :: m a -> Default m a
- Control.Effect.Machinery.Default: [runDefault] :: Default m a -> m a
- Control.Effect.Machinery.Default: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: instance Control.Monad.Trans.Class.MonadTrans Control.Effect.Machinery.Default.Default
- Control.Effect.Machinery.Default: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: instance Control.Monad.Trans.Control.MonadTransControl Control.Effect.Machinery.Default.Default
- Control.Effect.Machinery.Default: instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: instance GHC.Base.Functor m => GHC.Base.Functor (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: instance GHC.Base.Monad m => GHC.Base.Monad (Control.Effect.Machinery.Default.Default m)
- Control.Effect.Machinery.Default: newtype Default m a
+ Control.Effect.Embed: class Monad m => Embed' tag n m | tag m -> n
+ Control.Effect.Embed: data Finalization m a
+ Control.Effect.Embed: embed' :: Embed' tag n m => n a -> m a
+ Control.Effect.Embed: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance Control.Monad.Trans.Class.MonadTrans Control.Effect.Embed.Finalization
+ Control.Effect.Embed: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance Control.Monad.Trans.Control.MonadTransControl Control.Effect.Embed.Finalization
+ Control.Effect.Embed: instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance GHC.Base.Functor m => GHC.Base.Functor (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance GHC.Base.Monad m => GHC.Base.Monad (Control.Effect.Embed.Finalization m)
+ Control.Effect.Embed: instance forall k (n :: * -> *) (tag :: k). GHC.Base.Monad n => Control.Effect.Embed.Embed' tag n (Control.Effect.Embed.Finalization n)
+ Control.Effect.Embed: instance forall k (tag :: k) (n :: * -> *) (effs :: [Control.Effect.Machinery.Via.Effect]) (t :: Control.Effect.Machinery.Via.SomeMonad -> * -> *) (m :: * -> *) (other :: Control.Effect.Machinery.Via.Effect). Control.Effect.Machinery.Via.Find (Control.Effect.Embed.Embed' tag n) effs t m => Control.Effect.Embed.Embed' tag n (Control.Effect.Machinery.Via.EachVia (other : effs) t m)
+ Control.Effect.Embed: instance forall k (tag :: k) (n :: * -> *) (t :: Control.Effect.Machinery.Via.Transformer) (m :: * -> *) (effs :: [(* -> *) -> GHC.Types.Constraint]). Control.Effect.Machinery.Via.Handle (Control.Effect.Embed.Embed' tag n) t m => Control.Effect.Embed.Embed' tag n (Control.Effect.Machinery.Via.EachVia (Control.Effect.Embed.Embed' tag n : effs) t m)
+ Control.Effect.Embed: instance forall k (tag :: k) (n :: * -> *) (t :: Control.Effect.Machinery.Via.Transformer) (m :: * -> *). Control.Effect.Machinery.Via.Lift (Control.Effect.Embed.Embed' tag n) t m => Control.Effect.Embed.Embed' tag n (Control.Effect.Machinery.Via.EachVia '[] t m)
+ Control.Effect.Embed: instance forall k (tag :: k) (t :: * -> *) (m :: * -> *) (n :: * -> *). Control.Effect.Embed.Embed' tag t m => Control.Effect.Embed.Embed' tag n (Control.Effect.Embed.Transformation n t m)
+ Control.Effect.Embed: instance forall k (tag :: k). Control.Effect.Embed.Embed' tag Data.Functor.Identity.Identity Data.Functor.Identity.Identity
+ Control.Effect.Embed: instance forall k (tag :: k). Control.Effect.Embed.Embed' tag GHC.Maybe.Maybe GHC.Maybe.Maybe
+ Control.Effect.Embed: instance forall k (tag :: k). Control.Effect.Embed.Embed' tag GHC.Types.IO GHC.Types.IO
+ Control.Effect.Embed: instance forall k (tag :: k). Control.Effect.Embed.Embed' tag [] []
+ Control.Effect.Embed: instance forall k1 k2 (new :: k1) (n :: * -> *) (m :: * -> *) (tag :: k2). Control.Effect.Embed.Embed' new n m => Control.Effect.Embed.Embed' tag n (Control.Effect.Machinery.Tagger.Tagger tag new m)
+ Control.Effect.Embed: retagEmbed' :: forall tag_aiaR new_aiaS n_ai9M m_aiaV a_aiaW. Via (Embed' tag_aiaR n_ai9M) (Tagger tag_aiaR new_aiaS) m_aiaV a_aiaW -> m_aiaV a_aiaW
+ Control.Effect.Embed: runEmbed' :: forall tag n t m a. (forall b. n b -> t b) -> (Embed' tag n `Via` Transformation n t) m a -> m a
+ Control.Effect.Embed: runFinal :: (Embed m `Via` Finalization) m a -> m a
+ Control.Effect.Embed: runFinal' :: (Embed' tag m `Via` Finalization) m a -> m a
+ Control.Effect.Embed: tagEmbed' :: forall new_aiaS n_ai9M m_aiaT a_aiaU. Via (Embed' G n_ai9M) (Tagger G new_aiaS) m_aiaT a_aiaU -> m_aiaT a_aiaU
+ Control.Effect.Embed: type Embed n_ai9M = Embed' G n_ai9M
+ Control.Effect.Embed: untagEmbed' :: forall tag_aiaR n_ai9M m_aiaX a_aiaY. Via (Embed' tag_aiaR n_ai9M) (Tagger tag_aiaR G) m_aiaX a_aiaY -> m_aiaX a_aiaY
+ Control.Effect.Managed: class Monad m => Managed' tag m
+ Control.Effect.Managed: data Bracket n m a
+ Control.Effect.Managed: instance Control.Monad.Base.MonadBase b m => Control.Monad.Base.MonadBase b (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance Control.Monad.Trans.Class.MonadTrans (Control.Effect.Managed.Bracket n)
+ Control.Effect.Managed: instance Control.Monad.Trans.Control.MonadBaseControl b m => Control.Monad.Trans.Control.MonadBaseControl b (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance Control.Monad.Trans.Control.MonadTransControl (Control.Effect.Managed.Bracket n)
+ Control.Effect.Managed: instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance GHC.Base.Functor m => GHC.Base.Functor (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance GHC.Base.Monad m => GHC.Base.Monad (Control.Effect.Managed.Bracket n m)
+ Control.Effect.Managed: instance forall k (m :: * -> *) (tag :: k). Control.Monad.Base.MonadBase GHC.Types.IO m => Control.Effect.Managed.Managed' tag (Control.Effect.Managed.Bracket m m)
+ Control.Effect.Managed: instance forall k (tag :: k) (effs :: [Control.Effect.Machinery.Via.Effect]) (t :: Control.Effect.Machinery.Via.SomeMonad -> * -> *) (m :: * -> *) (other :: Control.Effect.Machinery.Via.Effect). Control.Effect.Machinery.Via.Find (Control.Effect.Managed.Managed' tag) effs t m => Control.Effect.Managed.Managed' tag (Control.Effect.Machinery.Via.EachVia (other : effs) t m)
+ Control.Effect.Managed: instance forall k (tag :: k) (t :: Control.Effect.Machinery.Via.Transformer) (m :: * -> *) (effs :: [(* -> *) -> GHC.Types.Constraint]). Control.Effect.Machinery.Via.Handle (Control.Effect.Managed.Managed' tag) t m => Control.Effect.Managed.Managed' tag (Control.Effect.Machinery.Via.EachVia (Control.Effect.Managed.Managed' tag : effs) t m)
+ Control.Effect.Managed: instance forall k (tag :: k) (t :: Control.Effect.Machinery.Via.Transformer) (m :: * -> *). Control.Effect.Machinery.Via.Control (Control.Effect.Managed.Managed' tag) t m => Control.Effect.Managed.Managed' tag (Control.Effect.Machinery.Via.EachVia '[] t m)
+ Control.Effect.Managed: instance forall k1 k2 (new :: k1) (m :: * -> *) (tag :: k2). Control.Effect.Managed.Managed' new m => Control.Effect.Managed.Managed' tag (Control.Effect.Machinery.Tagger.Tagger tag new m)
+ Control.Effect.Managed: manage :: Managed m_akJq => m_akJq a_akJr -> (a_akJr -> m_akJq b_akJs) -> m_akJq a_akJr
+ Control.Effect.Managed: manage' :: Managed' tag m => m a -> (a -> m b) -> m a
+ Control.Effect.Managed: retagManaged' :: forall tag_akKO new_akKP m_akKS a_akKT. Via (Managed' tag_akKO) (Tagger tag_akKO new_akKP) m_akKS a_akKT -> m_akKS a_akKT
+ Control.Effect.Managed: runManaged :: MonadBaseControl IO m => (Managed `Via` Bracket m) m a -> m a
+ Control.Effect.Managed: runManaged' :: forall tag m a. MonadBaseControl IO m => (Managed' tag `Via` Bracket m) m a -> m a
+ Control.Effect.Managed: tagManaged' :: forall new_akKP m_akKQ a_akKR. Via (Managed' G) (Tagger G new_akKP) m_akKQ a_akKR -> m_akKQ a_akKR
+ Control.Effect.Managed: type Managed = Managed' G
+ Control.Effect.Managed: untagManaged' :: forall tag_akKO m_akKU a_akKV. Via (Managed' tag_akKO) (Tagger tag_akKO G) m_akKU a_akKV -> m_akKU a_akKV
- Control.Effect.Cont: callCC :: Cont m_ajXN => ((a_ajXO -> m_ajXN b_ajXP) -> m_ajXN a_ajXO) -> m_ajXN a_ajXO
+ Control.Effect.Cont: callCC :: Cont m_ak9C => ((a_ak9D -> m_ak9C b_ak9E) -> m_ak9C a_ak9D) -> m_ak9C a_ak9D
- Control.Effect.Cont: retagCont' :: forall tag_ak3M new_ak3N m_ak3Q a_ak3R. Via (Cont' tag_ak3M) (Tagger tag_ak3M new_ak3N) m_ak3Q a_ak3R -> m_ak3Q a_ak3R
+ Control.Effect.Cont: retagCont' :: forall tag_akfB new_akfC m_akfF a_akfG. Via (Cont' tag_akfB) (Tagger tag_akfB new_akfC) m_akfF a_akfG -> m_akfF a_akfG
- Control.Effect.Cont: tagCont' :: forall new_ak3N m_ak3O a_ak3P. Via (Cont' G) (Tagger G new_ak3N) m_ak3O a_ak3P -> m_ak3O a_ak3P
+ Control.Effect.Cont: tagCont' :: forall new_akfC m_akfD a_akfE. Via (Cont' G) (Tagger G new_akfC) m_akfD a_akfE -> m_akfD a_akfE
- Control.Effect.Cont: untagCont' :: forall tag_ak3M m_ak3S a_ak3T. Via (Cont' tag_ak3M) (Tagger tag_ak3M G) m_ak3S a_ak3T -> m_ak3S a_ak3T
+ Control.Effect.Cont: untagCont' :: forall tag_akfB m_akfH a_akfI. Via (Cont' tag_akfB) (Tagger tag_akfB G) m_akfH a_akfI -> m_akfH a_akfI
- Control.Effect.Embed: embed :: Embed n m => n a -> m a
+ Control.Effect.Embed: embed :: Embed n_ai9M m_ai9N => n_ai9M a_ai9O -> m_ai9N a_ai9O
- Control.Effect.Error: catchError :: Error e_ai33 m_ai34 => m_ai34 a_ai36 -> (e_ai33 -> m_ai34 a_ai36) -> m_ai34 a_ai36
+ Control.Effect.Error: catchError :: Error e_ahqL m_ahqM => m_ahqM a_ahqO -> (e_ahqL -> m_ahqM a_ahqO) -> m_ahqM a_ahqO
- Control.Effect.Error: retagError' :: forall tag_ai55 new_ai56 e_ai33 m_ai59 a_ai5a. Via (Error' tag_ai55 e_ai33) (Tagger tag_ai55 new_ai56) m_ai59 a_ai5a -> m_ai59 a_ai5a
+ Control.Effect.Error: retagError' :: forall tag_ahsN new_ahsO e_ahqL m_ahsR a_ahsS. Via (Error' tag_ahsN e_ahqL) (Tagger tag_ahsN new_ahsO) m_ahsR a_ahsS -> m_ahsR a_ahsS
- Control.Effect.Error: tagError' :: forall new_ai56 e_ai33 m_ai57 a_ai58. Via (Error' G e_ai33) (Tagger G new_ai56) m_ai57 a_ai58 -> m_ai57 a_ai58
+ Control.Effect.Error: tagError' :: forall new_ahsO e_ahqL m_ahsP a_ahsQ. Via (Error' G e_ahqL) (Tagger G new_ahsO) m_ahsP a_ahsQ -> m_ahsP a_ahsQ
- Control.Effect.Error: throwError :: Error e_ai33 m_ai34 => e_ai33 -> m_ai34 a_ai35
+ Control.Effect.Error: throwError :: Error e_ahqL m_ahqM => e_ahqL -> m_ahqM a_ahqN
- Control.Effect.Error: type Error e_ai33 = Error' G e_ai33
+ Control.Effect.Error: type Error e_ahqL = Error' G e_ahqL
- Control.Effect.Error: untagError' :: forall tag_ai55 e_ai33 m_ai5b a_ai5c. Via (Error' tag_ai55 e_ai33) (Tagger tag_ai55 G) m_ai5b a_ai5c -> m_ai5b a_ai5c
+ Control.Effect.Error: untagError' :: forall tag_ahsN e_ahqL m_ahsT a_ahsU. Via (Error' tag_ahsN e_ahqL) (Tagger tag_ahsN G) m_ahsT a_ahsU -> m_ahsT a_ahsU
- Control.Effect.Map: clear :: Map k_akwz v_akwA m_akwB => m_akwB ()
+ Control.Effect.Map: clear :: Map k_ammu v_ammv m_ammw => m_ammw ()
- Control.Effect.Map: lookup :: Map k_akwz v_akwA m_akwB => k_akwz -> m_akwB (Maybe v_akwA)
+ Control.Effect.Map: lookup :: Map k_ammu v_ammv m_ammw => k_ammu -> m_ammw (Maybe v_ammv)
- Control.Effect.Map: retagMap' :: forall tag_akyE new_akyF k_akwz v_akwA m_akyI a_akyJ. Via (Map' tag_akyE k_akwz v_akwA) (Tagger tag_akyE new_akyF) m_akyI a_akyJ -> m_akyI a_akyJ
+ Control.Effect.Map: retagMap' :: forall tag_amoz new_amoA k_ammu v_ammv m_amoD a_amoE. Via (Map' tag_amoz k_ammu v_ammv) (Tagger tag_amoz new_amoA) m_amoD a_amoE -> m_amoD a_amoE
- Control.Effect.Map: tagMap' :: forall new_akyF k_akwz v_akwA m_akyG a_akyH. Via (Map' G k_akwz v_akwA) (Tagger G new_akyF) m_akyG a_akyH -> m_akyG a_akyH
+ Control.Effect.Map: tagMap' :: forall new_amoA k_ammu v_ammv m_amoB a_amoC. Via (Map' G k_ammu v_ammv) (Tagger G new_amoA) m_amoB a_amoC -> m_amoB a_amoC
- Control.Effect.Map: type Map k_akwz v_akwA = Map' G k_akwz v_akwA
+ Control.Effect.Map: type Map k_ammu v_ammv = Map' G k_ammu v_ammv
- Control.Effect.Map: untagMap' :: forall tag_akyE k_akwz v_akwA m_akyK a_akyL. Via (Map' tag_akyE k_akwz v_akwA) (Tagger tag_akyE G) m_akyK a_akyL -> m_akyK a_akyL
+ Control.Effect.Map: untagMap' :: forall tag_amoz k_ammu v_ammv m_amoF a_amoG. Via (Map' tag_amoz k_ammu v_ammv) (Tagger tag_amoz G) m_amoF a_amoG -> m_amoF a_amoG
- Control.Effect.Map: update :: Map k_akwz v_akwA m_akwB => k_akwz -> Maybe v_akwA -> m_akwB ()
+ Control.Effect.Map: update :: Map k_ammu v_ammv m_ammw => k_ammu -> Maybe v_ammv -> m_ammw ()
- Control.Effect.Reader: ask :: Reader r_an2M m_an2N => m_an2N r_an2M
+ Control.Effect.Reader: ask :: Reader r_aoSH m_aoSI => m_aoSI r_aoSH
- Control.Effect.Reader: local :: Reader r_an2M m_an2N => (r_an2M -> r_an2M) -> m_an2N a_an2O -> m_an2N a_an2O
+ Control.Effect.Reader: local :: Reader r_aoSH m_aoSI => (r_aoSH -> r_aoSH) -> m_aoSI a_aoSJ -> m_aoSI a_aoSJ
- Control.Effect.Reader: reader :: Reader r_an2M m_an2N => (r_an2M -> a_an2P) -> m_an2N a_an2P
+ Control.Effect.Reader: reader :: Reader r_aoSH m_aoSI => (r_aoSH -> a_aoSK) -> m_aoSI a_aoSK
- Control.Effect.Reader: retagReader' :: forall tag_an5F new_an5G r_an2M m_an5J a_an5K. Via (Reader' tag_an5F r_an2M) (Tagger tag_an5F new_an5G) m_an5J a_an5K -> m_an5J a_an5K
+ Control.Effect.Reader: retagReader' :: forall tag_aoVA new_aoVB r_aoSH m_aoVE a_aoVF. Via (Reader' tag_aoVA r_aoSH) (Tagger tag_aoVA new_aoVB) m_aoVE a_aoVF -> m_aoVE a_aoVF
- Control.Effect.Reader: tagReader' :: forall new_an5G r_an2M m_an5H a_an5I. Via (Reader' G r_an2M) (Tagger G new_an5G) m_an5H a_an5I -> m_an5H a_an5I
+ Control.Effect.Reader: tagReader' :: forall new_aoVB r_aoSH m_aoVC a_aoVD. Via (Reader' G r_aoSH) (Tagger G new_aoVB) m_aoVC a_aoVD -> m_aoVC a_aoVD
- Control.Effect.Reader: type Reader r_an2M = Reader' G r_an2M
+ Control.Effect.Reader: type Reader r_aoSH = Reader' G r_aoSH
- Control.Effect.Reader: untagReader' :: forall tag_an5F r_an2M m_an5L a_an5M. Via (Reader' tag_an5F r_an2M) (Tagger tag_an5F G) m_an5L a_an5M -> m_an5L a_an5M
+ Control.Effect.Reader: untagReader' :: forall tag_aoVA r_aoSH m_aoVG a_aoVH. Via (Reader' tag_aoVA r_aoSH) (Tagger tag_aoVA G) m_aoVG a_aoVH -> m_aoVG a_aoVH
- Control.Effect.Resource: bracket :: Resource m_anUP => m_anUP a_anUQ -> (a_anUQ -> m_anUP c_anUR) -> (a_anUQ -> m_anUP b_anUS) -> m_anUP b_anUS
+ Control.Effect.Resource: bracket :: Resource m_apK8 => m_apK8 a_apK9 -> (a_apK9 -> m_apK8 c_apKa) -> (a_apK9 -> m_apK8 b_apKb) -> m_apK8 b_apKb
- Control.Effect.Resource: bracketOnError :: Resource m_anUP => m_anUP a_anUT -> (a_anUT -> m_anUP c_anUU) -> (a_anUT -> m_anUP b_anUV) -> m_anUP b_anUV
+ Control.Effect.Resource: bracketOnError :: Resource m_apK8 => m_apK8 a_apKc -> (a_apKc -> m_apK8 c_apKd) -> (a_apKc -> m_apK8 b_apKe) -> m_apK8 b_apKe
- Control.Effect.Resource: retagResource' :: forall tag_anY1 new_anY2 m_anY5 a_anY6. Via (Resource' tag_anY1) (Tagger tag_anY1 new_anY2) m_anY5 a_anY6 -> m_anY5 a_anY6
+ Control.Effect.Resource: retagResource' :: forall tag_apNk new_apNl m_apNo a_apNp. Via (Resource' tag_apNk) (Tagger tag_apNk new_apNl) m_apNo a_apNp -> m_apNo a_apNp
- Control.Effect.Resource: tagResource' :: forall new_anY2 m_anY3 a_anY4. Via (Resource' G) (Tagger G new_anY2) m_anY3 a_anY4 -> m_anY3 a_anY4
+ Control.Effect.Resource: tagResource' :: forall new_apNl m_apNm a_apNn. Via (Resource' G) (Tagger G new_apNl) m_apNm a_apNn -> m_apNm a_apNn
- Control.Effect.Resource: untagResource' :: forall tag_anY1 m_anY7 a_anY8. Via (Resource' tag_anY1) (Tagger tag_anY1 G) m_anY7 a_anY8 -> m_anY7 a_anY8
+ Control.Effect.Resource: untagResource' :: forall tag_apNk m_apNq a_apNr. Via (Resource' tag_apNk) (Tagger tag_apNk G) m_apNq a_apNr -> m_apNq a_apNr
- Control.Effect.State: get :: State s_aq02 m_aq03 => m_aq03 s_aq02
+ Control.Effect.State: get :: State s_arHH m_arHI => m_arHI s_arHH
- Control.Effect.State: put :: State s_aq02 m_aq03 => s_aq02 -> m_aq03 ()
+ Control.Effect.State: put :: State s_arHH m_arHI => s_arHH -> m_arHI ()
- Control.Effect.State: retagState' :: forall tag_aq32 new_aq33 s_aq02 m_aq36 a_aq37. Via (State' tag_aq32 s_aq02) (Tagger tag_aq32 new_aq33) m_aq36 a_aq37 -> m_aq36 a_aq37
+ Control.Effect.State: retagState' :: forall tag_arKH new_arKI s_arHH m_arKL a_arKM. Via (State' tag_arKH s_arHH) (Tagger tag_arKH new_arKI) m_arKL a_arKM -> m_arKL a_arKM
- Control.Effect.State: state :: State s_aq02 m_aq03 => (s_aq02 -> (s_aq02, a_aq04)) -> m_aq03 a_aq04
+ Control.Effect.State: state :: State s_arHH m_arHI => (s_arHH -> (s_arHH, a_arHJ)) -> m_arHI a_arHJ
- Control.Effect.State: tagState' :: forall new_aq33 s_aq02 m_aq34 a_aq35. Via (State' G s_aq02) (Tagger G new_aq33) m_aq34 a_aq35 -> m_aq34 a_aq35
+ Control.Effect.State: tagState' :: forall new_arKI s_arHH m_arKJ a_arKK. Via (State' G s_arHH) (Tagger G new_arKI) m_arKJ a_arKK -> m_arKJ a_arKK
- Control.Effect.State: type State s_aq02 = State' G s_aq02
+ Control.Effect.State: type State s_arHH = State' G s_arHH
- Control.Effect.State: untagState' :: forall tag_aq32 s_aq02 m_aq38 a_aq39. Via (State' tag_aq32 s_aq02) (Tagger tag_aq32 G) m_aq38 a_aq39 -> m_aq38 a_aq39
+ Control.Effect.State: untagState' :: forall tag_arKH s_arHH m_arKN a_arKO. Via (State' tag_arKH s_arHH) (Tagger tag_arKH G) m_arKN a_arKO -> m_arKN a_arKO
- Control.Effect.Writer: censor :: Writer w_araD m_araE => (w_araD -> w_araD) -> m_araE a_araG -> m_araE a_araG
+ Control.Effect.Writer: censor :: Writer w_asSi m_asSj => (w_asSi -> w_asSi) -> m_asSj a_asSl -> m_asSj a_asSl
- Control.Effect.Writer: listen :: Writer w_araD m_araE => m_araE a_araF -> m_araE (w_araD, a_araF)
+ Control.Effect.Writer: listen :: Writer w_asSi m_asSj => m_asSj a_asSk -> m_asSj (w_asSi, a_asSk)
- Control.Effect.Writer: retagWriter' :: forall tag_ard6 new_ard7 w_araD m_arda a_ardb. Via (Writer' tag_ard6 w_araD) (Tagger tag_ard6 new_ard7) m_arda a_ardb -> m_arda a_ardb
+ Control.Effect.Writer: retagWriter' :: forall tag_asUL new_asUM w_asSi m_asUP a_asUQ. Via (Writer' tag_asUL w_asSi) (Tagger tag_asUL new_asUM) m_asUP a_asUQ -> m_asUP a_asUQ
- Control.Effect.Writer: tagWriter' :: forall new_ard7 w_araD m_ard8 a_ard9. Via (Writer' G w_araD) (Tagger G new_ard7) m_ard8 a_ard9 -> m_ard8 a_ard9
+ Control.Effect.Writer: tagWriter' :: forall new_asUM w_asSi m_asUN a_asUO. Via (Writer' G w_asSi) (Tagger G new_asUM) m_asUN a_asUO -> m_asUN a_asUO
- Control.Effect.Writer: tell :: Writer w_araD m_araE => w_araD -> m_araE ()
+ Control.Effect.Writer: tell :: Writer w_asSi m_asSj => w_asSi -> m_asSj ()
- Control.Effect.Writer: type Writer w_araD = Writer' G w_araD
+ Control.Effect.Writer: type Writer w_asSi = Writer' G w_asSi
- Control.Effect.Writer: untagWriter' :: forall tag_ard6 w_araD m_ardc a_ardd. Via (Writer' tag_ard6 w_araD) (Tagger tag_ard6 G) m_ardc a_ardd -> m_ardc a_ardd
+ Control.Effect.Writer: untagWriter' :: forall tag_asUL w_asSi m_asUR a_asUS. Via (Writer' tag_asUL w_asSi) (Tagger tag_asUL G) m_asUR a_asUS -> m_asUR a_asUS
Files
- ChangeLog.md +7/−1
- README.md +2/−2
- effet.cabal +4/−4
- src/Control/Effect/Embed.hs +106/−16
- src/Control/Effect/Machinery.hs +4/−4
- src/Control/Effect/Machinery/Default.hs +0/−54
- src/Control/Effect/Machinery/Tagger.hs +3/−4
- src/Control/Effect/Machinery/Via.hs +140/−140
- src/Control/Effect/Managed.hs +122/−0
- src/Control/Effect/RWS.hs +2/−2
- src/Control/Effect/Resource.hs +1/−1
ChangeLog.md view
@@ -7,4 +7,10 @@ ## 0.2.0.0 (2020-07-29) * Lifted the restriction that one handler can exactly handle one effect. Handlers can now handle multiple effects. -* Effects whose definitions refer to other effects (see the RWS effect, for example) are now possible to implement, but only manually for now (i.e., no code generation).+* Effects whose definitions refer to other effects (see the RWS effect, for example) are now possible to implement, but only manually for now (i.e., no code generation). + +## 0.3.0.0 (2020-10-13) + +* Adapted the embed effect which now supports tagging/retagging/untagging. +* Introduced the managed effect. +* Relaxed bounds a bit for better compilation.
README.md view
@@ -108,7 +108,7 @@ newtype LocalFS m a = LocalFS { runLocalFS :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b) ``` @@ -142,7 +142,7 @@ newtype VirtualFS m a = VirtualFS { runVirtualFS :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b) instance Map' tag FilePath String m => FileSystem' tag (VirtualFS m) where
effet.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 397bba600623b58701020a4ec01a2dff5e707d155f8f98e84f63423537604919+-- hash: df92fee8597297b24a1a0e0ac46f0b028382ad585bd69cc307e0701203bd4502 name: effet-version: 0.2.0.0+version: 0.3.0.0 synopsis: An Effect System based on Type Classes description: Please see the README on GitHub at <https://github.com/typedbyte/effet#readme> category: Control@@ -33,10 +33,10 @@ Control.Effect.Embed Control.Effect.Error Control.Effect.Machinery- Control.Effect.Machinery.Default Control.Effect.Machinery.Tagger Control.Effect.Machinery.TH Control.Effect.Machinery.Via+ Control.Effect.Managed Control.Effect.Map Control.Effect.Map.Lazy Control.Effect.Map.Strict@@ -61,7 +61,7 @@ base >=4.7 && <5 , containers >=0.6.2.1 && <0.7 , monad-control >=1.0.2.3 && <1.1- , template-haskell >=2.15.0.0 && <2.16+ , template-haskell >=2.14.0.0 && <3 , transformers >=0.5.6.2 && <0.6 , transformers-base >=0.4.5.2 && <0.5 default-language: Haskell2010
src/Control/Effect/Embed.hs view
@@ -11,32 +11,77 @@ -- The embed effect for integrating arbitrary monads into the effect system. ----------------------------------------------------------------------------- module Control.Effect.Embed- ( -- * Embed Effect- Embed(..)+ ( -- * Tagged Embed Effect+ Embed'(..)+ -- * Untagged Embed Effect+ -- | If you don't require disambiguation of multiple embed effects+ -- (i.e., you only have one embed effect in your monadic context),+ -- it is recommended to always use the untagged embed effect.+ , Embed+ , embed -- * Interpretations+ -- ** Via Transformation , Transformation+ , runEmbed' , runEmbed+ -- ** Via Finalization+ , Finalization+ , runFinal'+ , runFinal+ -- * Tagging and Untagging+ -- | Conversion functions between the tagged and untagged embed effect,+ -- usually used in combination with type applications, like:+ --+ -- @+ -- 'tagEmbed'' \@\"newTag\" program+ -- 'retagEmbed'' \@\"oldTag\" \@\"newTag\" program+ -- 'untagEmbed'' \@\"erasedTag\" program+ -- @+ -- + , tagEmbed'+ , retagEmbed'+ , untagEmbed' ) where +-- base+import Data.Coerce (coerce)+import Data.Functor.Identity (Identity)+ -- transformers import Control.Monad.Trans.Reader (ReaderT(ReaderT), runReaderT) import Control.Effect.Machinery hiding (embed) -- | An effect that integrates a monad @n@ into the computation @m@.-class Monad m => Embed n m where+--+-- @since 0.3.0.0+class Monad m => Embed' tag n m | tag m -> n where -- | Monadic actions in @n@ can be lifted into @m@ via 'embed'. -- -- 'embed' is like 'liftIO', but not limited to 'IO'. In fact, 'liftIO' can -- be realized using 'embed' by specializing @n@ to @IO@.- embed :: n a -> m a+ --+ -- @since 0.3.0.0+ embed' :: n a -> m a -makeEffect ''Embed+makeTaggedEffect ''Embed' -instance Monad m => Embed m m where- embed = id- {-# INLINE embed #-}+instance Embed' tag IO IO where+ embed' = id+ {-# INLINE embed' #-} +instance Embed' tag Maybe Maybe where+ embed' = id+ {-# INLINE embed' #-}++instance Embed' tag [] [] where+ embed' = id+ {-# INLINE embed' #-}++instance Embed' tag Identity Identity where+ embed' = id+ {-# INLINE embed' #-}+ newtype F n t = F (forall b. n b -> t b) -- | The transformation interpreter of the embed effect. This type implements the@@ -51,15 +96,60 @@ deriving (MonadTrans, MonadTransControl) deriving (MonadBase b, MonadBaseControl b) -instance Embed t m => Embed n (Transformation n t m) where- embed na = Transformation . ReaderT $- \(F f) -> embed (f na)- {-# INLINE embed #-}+instance Embed' tag t m => Embed' tag n (Transformation n t m) where+ embed' na = Transformation . ReaderT $+ \(F f) -> embed' @tag (f na)+ {-# INLINE embed' #-} -- | Runs the embed effect by transforming the integrated monad @n@ into another -- integrated monad @t@.-runEmbed :: (forall b. n b -> t b) -- ^ The natural transformation from monad @n@ to monad @t@.- -> (Embed n `Via` Transformation n t) m a -- ^ The program whose embed effect should be handled.- -> m a -- ^ The program with its embed effect handled.-runEmbed f = flip runReaderT (F f) . runTransformation . runVia+--+-- @since 0.3.0.0+runEmbed' :: forall tag n t m a+ . (forall b. n b -> t b) -- ^ The natural transformation from monad @n@ to monad @t@.+ -> (Embed' tag n `Via` Transformation n t) m a -- ^ The program whose embed effect should be handled.+ -> m a -- ^ The program with its embed effect handled.+runEmbed' f = flip runReaderT (F f) . runTransformation . runVia+{-# INLINE runEmbed' #-}++-- | The untagged version of 'runEmbed''.+runEmbed :: (forall b. n b -> t b) -> (Embed n `Via` Transformation n t) m a -> m a+runEmbed = runEmbed' @G {-# INLINE runEmbed #-}++-- | The finalization interpreter of the embed effect. This type implements the+-- 'Embed' type class by declaring the integrated monad the final monad @m@+-- (also called the \"base monad\").+--+-- Chances are very high that you only need this interpreter if you have a+-- custom final monad because the 'Embed'' effect is already implemented for+-- final monads like 'IO', 'Maybe', @[]@ and 'Identity'.+--+-- When interpreting the effect, you usually don\'t interact with this type directly,+-- but instead use one of its corresponding interpretation functions.+--+-- @since 0.3.0.0+newtype Finalization m a =+ Finalization { _runFinalization :: m a }+ deriving (Applicative, Functor, Monad, MonadIO)+ deriving (MonadTrans, MonadTransControl) via IdentityT+ deriving (MonadBase b, MonadBaseControl b)++instance Monad n => Embed' tag n (Finalization n) where+ embed' = Finalization+ {-# INLINE embed' #-}++-- | Runs the embed effect by declaring the integrated monad the final monad.+--+-- @since 0.3.0.0+runFinal' :: (Embed' tag m `Via` Finalization) m a -- ^ The program whose embed effect should be handled.+ -> m a -- ^ The program with its embed effect handled.+runFinal' = coerce+{-# INLINE runFinal' #-}++-- | The untagged version of 'runFinal''.+--+-- @since 0.3.0.0+runFinal :: (Embed m `Via` Finalization) m a -> m a+runFinal = runFinal' @G+{-# INLINE runFinal #-}
src/Control/Effect/Machinery.hs view
@@ -13,8 +13,7 @@ ----------------------------------------------------------------------------- module Control.Effect.Machinery ( -- * Re-exports from @effet@- module Control.Effect.Machinery.Default- , module Control.Effect.Machinery.Tagger+ module Control.Effect.Machinery.Tagger , module Control.Effect.Machinery.TH , module Control.Effect.Machinery.Via -- * Re-exports from @base@@@ -23,6 +22,7 @@ , module Control.Monad.Trans.Control -- * Re-exports from @transformers@ , module Control.Monad.Trans.Class+ , module Control.Monad.Trans.Identity -- * Re-exports from @transformers-base@ , module Control.Monad.Base ) where@@ -31,15 +31,15 @@ import Control.Monad.IO.Class -- monad-control-import Control.Monad.Trans.Control -- hiding (embed)+import Control.Monad.Trans.Control -- transformers import Control.Monad.Trans.Class+import Control.Monad.Trans.Identity -- transformers-base import Control.Monad.Base -import Control.Effect.Machinery.Default import Control.Effect.Machinery.Tagger import Control.Effect.Machinery.TH import Control.Effect.Machinery.Via
− src/Control/Effect/Machinery/Default.hs
@@ -1,54 +0,0 @@--------------------------------------------------------------------------------- |--- Module : Control.Effect.Machinery.Default--- Copyright : (c) Michael Szvetits, 2020--- License : BSD3 (see the file LICENSE)--- Maintainer : typedbyte@qualified.name--- Stability : stable--- Portability : portable------ This module provides default implementations for the 'MonadTrans' and--- 'MonadTransControl' type classes.-------------------------------------------------------------------------------module Control.Effect.Machinery.Default (Default(..)) where---- base-import Control.Monad.IO.Class (MonadIO)---- monad-control-import Control.Monad.Trans.Control (MonadBaseControl, MonadTransControl, StT,- liftWith, restoreT)---- transformers-import Control.Monad.Trans.Class (MonadTrans, lift)---- transformers-base-import Control.Monad.Base (MonadBase)---- | This type provides default implementations for the 'MonadTrans' and--- 'MonadTransControl' type classes. The type is intended to be targeted by the--- @DerivingVia@ language extension when writing an effect handler newtype that--- wraps a monad @m a@ :------ @--- newtype MyHandler m a =--- MyHandler { runMyHandler :: m a }--- deriving (Applicative, Functor, Monad, MonadIO)--- deriving (MonadTrans, MonadTransControl) via 'Default'--- deriving (MonadBase b, MonadBaseControl b)--- @-newtype Default m a =- Default { runDefault :: m a }- deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadBase b, MonadBaseControl b)--instance MonadTrans Default where- lift = Default- {-# INLINE lift #-}--instance MonadTransControl Default where- type StT Default a = a- liftWith f = Default (f runDefault)- {-# INLINE liftWith #-}- restoreT = Default- {-# INLINE restoreT #-}
src/Control/Effect/Machinery/Tagger.hs view
@@ -19,13 +19,12 @@ import Control.Monad.Trans.Control (MonadBaseControl, MonadTransControl) -- transformers-import Control.Monad.Trans.Class (MonadTrans)+import Control.Monad.Trans.Class (MonadTrans)+import Control.Monad.Trans.Identity (IdentityT(IdentityT)) -- transformers-base import Control.Monad.Base (MonadBase) -import Control.Effect.Machinery.Default (Default(Default))- -- | This type provides instances for effect type classes in order to enable -- tagging, retagging and untagging of effects. Whenever this type is used as -- handler of an effect, the effect previously tagged with @tag@ will be@@ -37,5 +36,5 @@ newtype Tagger tag new m a = Tagger { runTagger :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b)
src/Control/Effect/Machinery/Via.hs view
@@ -1,141 +1,141 @@--------------------------------------------------------------------------------- |--- Module : Control.Effect.Machinery.Via--- Copyright : (c) Michael Szvetits, 2020--- License : BSD3 (see the file LICENSE)--- Maintainer : typedbyte@qualified.name--- Stability : stable--- Portability : portable------ This module defines the types 'EachVia' and its corresponding type synonym--- 'Via' which indicate that specific effects are handled by a specific monad--- transformer (also known as effect handler or effect interpreter).------ It also defines the 'G' type, which is the global tag that is used for--- untagged effects.--- --- Last but not least, it defines some constraint synonyms and kinds that are--- used throughout this library, hopefully to increase the readability of the--- code at some points.-------------------------------------------------------------------------------module Control.Effect.Machinery.Via- ( -- * Core Types- EachVia(..)- , Via- , G- -- * Constraint Synonyms and Kinds- , SomeMonad- , Effect- , Transformer- , Handle- , Find- , Lift- , Control- ) where---- base-import Control.Monad.IO.Class (MonadIO)-import Data.Kind (Constraint, Type)---- monad-control-import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl,- MonadTransControl, StM, defaultLiftBaseWith,- defaultRestoreM,liftBaseWith, restoreM)---- transformers-import Control.Monad.Trans.Class (MonadTrans)---- transformers-base-import Control.Monad.Base (MonadBase, liftBase, liftBaseDefault)---- | This type indicates that the effects (i.e., type classes) @effs@ are handled by--- a specific monad transformer @t@. The type is a simple wrapper around the--- monad transformer itself. The whole purpose of this type is to guide the type--- system to pick the instances of type classes @effs@ given by the type @t@, and--- to delegate all other effects that are not in @effs@ to their handlers which are--- located somewhere further down the monad transformer stack.------ @since 0.2.0.0-newtype EachVia (effs :: [Effect]) (t :: Transformer) m a =- EachVia { runVia :: t m a }- deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl)--instance (Monad (t m), MonadBase b m, MonadTrans t) => MonadBase b (EachVia effs t m) where- liftBase = liftBaseDefault- {-# INLINE liftBase #-}--instance (Monad (t m), MonadBaseControl b m, MonadTransControl t) => MonadBaseControl b (EachVia effs t m) where- type StM (EachVia effs t m) a = ComposeSt t m a- liftBaseWith = defaultLiftBaseWith- {-# INLINE liftBaseWith #-}- restoreM = defaultRestoreM- {-# INLINE restoreM #-}---- | This type synonym can be used to indicate that a single effect @eff@ is--- handled by a specific monad transformer @t@.------ @since 0.2.0.0-type Via eff t m a = EachVia '[eff] t m a---- | This type is used as tag for all untagged effects. In order words, every--- effect is tagged, even untagged ones, but all the untagged ones simply have--- the same tag @G@ (short for \"Global\", because you can view tags as some--- kind of namespace mechanism, and all untagged effects live in the same--- global namespace).------ If you don\'t want to use tagged effects (i.e., you write effect type classes--- without a tag type parameter), you can ignore this type completely.-data G---- | The kind of monads.-type SomeMonad = Type -> Type---- | The kind of effects, which are type classes with a monad type parameter at--- the end.-type Effect = SomeMonad -> Constraint---- | The kind of monad transformers, also known as effect handlers or effect--- interpreters.-type Transformer = SomeMonad -> Type -> Type---- | This type synonym indicates that an effect is handled by a specific monad--- transformer.-type Handle (eff :: Effect) (t :: Transformer) m =- eff (t m)---- | This type synonym indicates that an effect @eff@ is not at the head of the--- type level list of effects to be handled, so the effect must be found further--- down in the tail @effs@.------ @since 0.2.0.0-type Find eff effs t m = (Monad (t m), eff (EachVia effs t m))---- | This constraint synonym indicates that a first-order effect is not handled--- by a specific monad transformer and must thus be delegated (\"lifted\")--- further down the monad transformer stack in order to find its associated--- handler.------ Roughly speaking, a first-order effect is a type class whose monad type--- parameter @m@ appears only in positive position when looking at the types of--- its corresponding class methods (e.g., @m@ appears only in the result type).------ An example of a first-order effect is the 'Control.Effect.State.State'' effect.-type Lift (eff :: Effect) (t :: Transformer) m =- (eff m, Monad (t m), MonadTrans t)---- | This constraint synonym indicates that a higher-order effect is not handled--- by a specific monad transformer and must thus be delegated (\"lifted\")--- further down the monad transformer stack in order to find its associated--- handler.------ Roughly speaking, a higher-order effect is a type class whose monad type--- parameter @m@ appears in negative position when looking at the types of its--- corresponding class methods (e.g., @m@ appears in the type of a method--- parameter).------ An example of a higher-order effect is the 'Control.Effect.Reader.Reader'' effect,--- since its class method 'Control.Effect.Reader.local'' has a parameter of--- type @m a@.-type Control (eff :: Effect) (t :: Transformer) m =+----------------------------------------------------------------------------- +-- | +-- Module : Control.Effect.Machinery.Via +-- Copyright : (c) Michael Szvetits, 2020 +-- License : BSD3 (see the file LICENSE) +-- Maintainer : typedbyte@qualified.name +-- Stability : stable +-- Portability : portable +-- +-- This module defines the types 'EachVia' and its corresponding type synonym +-- 'Via' which indicate that specific effects are handled by a specific monad +-- transformer (also known as effect handler or effect interpreter). +-- +-- It also defines the 'G' type, which is the global tag that is used for +-- untagged effects. +-- +-- Last but not least, it defines some constraint synonyms and kinds that are +-- used throughout this library, hopefully to increase the readability of the +-- code at some points. +----------------------------------------------------------------------------- +module Control.Effect.Machinery.Via + ( -- * Core Types + EachVia(..) + , Via + , G + -- * Constraint Synonyms and Kinds + , SomeMonad + , Effect + , Transformer + , Handle + , Find + , Lift + , Control + ) where + +-- base +import Control.Monad.IO.Class (MonadIO) +import Data.Kind (Constraint, Type) + +-- monad-control +import Control.Monad.Trans.Control (ComposeSt, MonadBaseControl, + MonadTransControl, StM, defaultLiftBaseWith, + defaultRestoreM,liftBaseWith, restoreM) + +-- transformers +import Control.Monad.Trans.Class (MonadTrans) + +-- transformers-base +import Control.Monad.Base (MonadBase, liftBase, liftBaseDefault) + +-- | This type indicates that the effects (i.e., type classes) @effs@ are handled by +-- a specific monad transformer @t@. The type is a simple wrapper around the +-- monad transformer itself. The whole purpose of this type is to guide the type +-- system to pick the instances of type classes @effs@ given by the type @t@, and +-- to delegate all other effects that are not in @effs@ to their handlers which are +-- located somewhere further down the monad transformer stack. +-- +-- @since 0.2.0.0 +newtype EachVia (effs :: [Effect]) (t :: Transformer) m a = + EachVia { runVia :: t m a } + deriving (Applicative, Functor, Monad, MonadIO) + deriving (MonadTrans, MonadTransControl) + +instance (Monad (t m), MonadBase b m, MonadTrans t) => MonadBase b (EachVia effs t m) where + liftBase = liftBaseDefault + {-# INLINE liftBase #-} + +instance (Monad (t m), MonadBaseControl b m, MonadTransControl t) => MonadBaseControl b (EachVia effs t m) where + type StM (EachVia effs t m) a = ComposeSt t m a + liftBaseWith = defaultLiftBaseWith + {-# INLINE liftBaseWith #-} + restoreM = defaultRestoreM + {-# INLINE restoreM #-} + +-- | This type synonym can be used to indicate that a single effect @eff@ is +-- handled by a specific monad transformer @t@. +-- +-- @since 0.2.0.0 +type Via eff t m a = EachVia '[eff] t m a + +-- | This type is used as tag for all untagged effects. In order words, every +-- effect is tagged, even untagged ones, but all the untagged ones simply have +-- the same tag @G@ (short for \"Global\", because you can view tags as some +-- kind of namespace mechanism, and all untagged effects live in the same +-- global namespace). +-- +-- If you don\'t want to use tagged effects (i.e., you write effect type classes +-- without a tag type parameter), you can ignore this type completely. +data G + +-- | The kind of monads. +type SomeMonad = Type -> Type + +-- | The kind of effects, which are type classes with a monad type parameter at +-- the end. +type Effect = SomeMonad -> Constraint + +-- | The kind of monad transformers, also known as effect handlers or effect +-- interpreters. +type Transformer = SomeMonad -> Type -> Type + +-- | This constraint synonym indicates that an effect is handled by a specific monad +-- transformer. +type Handle (eff :: Effect) (t :: Transformer) m = + eff (t m) + +-- | This constraint synonym indicates that an effect @eff@ is not at the head of the +-- type level list of effects to be handled, so the effect must be found further +-- down in the tail @effs@. +-- +-- @since 0.2.0.0 +type Find eff effs t m = (Monad (t m), eff (EachVia effs t m)) + +-- | This constraint synonym indicates that a first-order effect is not handled +-- by a specific monad transformer and must thus be delegated (\"lifted\") +-- further down the monad transformer stack in order to find its associated +-- handler. +-- +-- Roughly speaking, a first-order effect is a type class whose monad type +-- parameter @m@ appears only in positive position when looking at the types of +-- its corresponding class methods (e.g., @m@ appears only in the result type). +-- +-- An example of a first-order effect is the 'Control.Effect.State.State'' effect. +type Lift (eff :: Effect) (t :: Transformer) m = + (eff m, Monad (t m), MonadTrans t) + +-- | This constraint synonym indicates that a higher-order effect is not handled +-- by a specific monad transformer and must thus be delegated (\"lifted\") +-- further down the monad transformer stack in order to find its associated +-- handler. +-- +-- Roughly speaking, a higher-order effect is a type class whose monad type +-- parameter @m@ appears in negative position when looking at the types of its +-- corresponding class methods (e.g., @m@ appears in the type of a method +-- parameter). +-- +-- An example of a higher-order effect is the 'Control.Effect.Reader.Reader'' effect, +-- since its class method 'Control.Effect.Reader.local'' has a parameter of +-- type @m a@. +type Control (eff :: Effect) (t :: Transformer) m = (eff m, Monad (t m), MonadTransControl t)
+ src/Control/Effect/Managed.hs view
@@ -0,0 +1,122 @@+{-# LANGUAGE TemplateHaskell #-}+-----------------------------------------------------------------------------+-- |+-- Module : Control.Effect.Managed+-- Copyright : (c) Michael Szvetits, 2020+-- License : BSD3 (see the file LICENSE)+-- Maintainer : typedbyte@qualified.name+-- Stability : stable+-- Portability : portable+--+-- The managed effect allows a computation to allocate resources which are+-- guaranteed to be released after the end of the computation. This effect+-- provides a monadic interface for managing one or more long-living+-- resources in a more readable way than nesting 'IO.bracket'-style+-- operations of the "Control.Effect.Resource" effect.+-----------------------------------------------------------------------------+module Control.Effect.Managed+ ( -- * Tagged Managed Effect+ Managed'(..)+ -- * Untagged Managed Effect+ -- | If you don't require disambiguation of multiple managed effects+ -- (i.e., you only have one managed effect in your monadic context),+ -- it is recommended to always use the untagged managed effect.+ , Managed+ , manage+ -- * Interpretations+ , Bracket+ , runManaged'+ , runManaged+ -- * Tagging and Untagging+ -- | Conversion functions between the tagged and untagged managed effect,+ -- usually used in combination with type applications, like:+ --+ -- @+ -- 'tagManaged'' \@\"newTag\" program+ -- 'retagManaged'' \@\"oldTag\" \@\"newTag\" program+ -- 'untagManaged'' \@\"erasedTag\" program+ -- @+ -- + , tagManaged'+ , retagManaged'+ , untagManaged'+ ) where++-- base+import qualified Control.Exception as IO+import Data.IORef (IORef, atomicModifyIORef', newIORef, readIORef)++-- transformers+import Control.Monad.Trans.Reader (ReaderT(ReaderT), runReaderT)++import Control.Effect.Machinery++-- | An effect that allows a computation to allocate resources which are+-- guaranteed to be released after the computation.+--+-- @since 0.3.0.0+class Monad m => Managed' tag m where+ -- | Acquire a resource by specifying an acquisition action and a release+ -- action to be used for cleanup after the computation.+ --+ -- @since 0.3.0.0+ manage' :: m a -- ^ The computation which acquires the resource.+ -> (a -> m b) -- ^ The computation which releases the resource.+ -> m a -- ^ The acquired resource.++makeTaggedEffect ''Managed'++-- | The bracket-based interpreter of the managed effect. This type implements+-- the 'Managed'' type class by using 'IO.bracket', thus requiring 'IO' at the+-- bottom of the monad transformer stack.+--+-- When interpreting the effect, you usually don\'t interact with this type directly,+-- but instead use one of its corresponding interpretation functions.+--+-- @since 0.3.0.0+newtype Bracket n m a = Bracket { runBracket :: ReaderT (IORef [n ()]) m a }+ deriving (Applicative, Functor, Monad, MonadIO)+ deriving (MonadTrans, MonadTransControl)+ deriving (MonadBase b, MonadBaseControl b)++instance MonadBase IO m => Managed' tag (Bracket m m) where+ manage' alloc free = Bracket . ReaderT $+ \ref -> do+ a <- runReaderT (runBracket alloc) ref+ liftBase $+ atomicModifyIORef' ref $+ \frees -> (runReaderT (runBracket (free a >> pure ())) ref : frees, ())+ pure a+ {-# INLINE manage' #-}++-- | Runs the managed effect using 'IO.bracket'.+--+-- @since 0.3.0.0+runManaged' :: forall tag m a. MonadBaseControl IO m => (Managed' tag `Via` Bracket m) m a -> m a+runManaged' program =+ liftedBracket+ ( allocRef )+ ( freeRef )+ ( runReaderT (runBracket (runVia program)) )+ where+ allocRef :: forall n. MonadBase IO n => n (IORef [n ()])+ allocRef = liftBase $ newIORef []+ + freeRef :: forall n. MonadBase IO n => IORef [n ()] -> n ()+ freeRef = (sequence_ =<<) . liftBase . readIORef+ + liftedBracket :: forall n b c d. MonadBaseControl IO n => n b -> (b -> n c) -> (b -> n d) -> n d+ liftedBracket alloc free use =+ control $ \run ->+ IO.bracket+ ( run alloc )+ ( \a -> run (restoreM a >>= free) )+ ( \a -> run (restoreM a >>= use) )+{-# INLINE runManaged' #-}++-- | The untagged version of 'runManaged''.+--+-- @since 0.3.0.0+runManaged :: MonadBaseControl IO m => (Managed `Via` Bracket m) m a -> m a+runManaged = runManaged' @G+{-# INLINE runManaged #-}
src/Control/Effect/RWS.hs view
@@ -89,7 +89,7 @@ newtype Separation m a = Separation { _runSeparation :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b) deriving (R.Reader' tag r, W.Writer' tag w, S.State' tag s) @@ -120,7 +120,7 @@ newtype Tagger tag new m a = Tagger { runRWSTagger :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b) instance RWS' new r w s m => RWS' tag r w s (Tagger tag new m)
src/Control/Effect/Resource.hs view
@@ -113,7 +113,7 @@ newtype LowerIO m a = LowerIO { _runLowerIO :: m a } deriving (Applicative, Functor, Monad, MonadIO)- deriving (MonadTrans, MonadTransControl) via Default+ deriving (MonadTrans, MonadTransControl) via IdentityT deriving (MonadBase b, MonadBaseControl b) instance MonadBaseControl IO m => Resource' tag (LowerIO m) where