packages feed

THEff 0.1.0.1 → 0.1.1.0

raw patch · 10 files changed

+415/−85 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Control.THEff.Reader.Strict: ReaderAction :: (Reader' v e) -> Reader e o v a
+ Control.THEff.Reader.Strict: ReaderOuter :: (o m e) -> Reader e o v a
+ Control.THEff.Reader.Strict: ReaderResult :: a -> Reader e o v a
+ Control.THEff.Reader.Strict: ask :: EffClass Reader' v e => Eff e v
+ Control.THEff.Reader.Strict: asks :: EffClass Reader' r e => (r -> v) -> Eff e v
+ Control.THEff.Reader.Strict: data Reader (m :: * -> *) e o v a
+ Control.THEff.Reader.Strict: data Reader' v e
+ Control.THEff.Reader.Strict: effReader :: EffClass Reader' v e => Reader' v r -> Eff e r
+ Control.THEff.Reader.Strict: runEffReader :: Monad m => (u t r -> (r -> m (ReaderResT a)) -> m (ReaderResT a)) -> (Reader m1 e o w a1 -> r) -> (r -> Reader t r u v a) -> ReaderArgT v -> Eff r a1 -> m (ReaderResT a)
+ Control.THEff.Reader.Strict: type ReaderArgT v = v
+ Control.THEff.Reader.Strict: type ReaderResT r = r
+ Control.THEff.State.Strict: StateAction :: (State' v e) -> State e o v a
+ Control.THEff.State.Strict: StateOuter :: (o m e) -> State e o v a
+ Control.THEff.State.Strict: StateResult :: a -> State e o v a
+ Control.THEff.State.Strict: data State (m :: * -> *) e o v a
+ Control.THEff.State.Strict: data State' v e
+ Control.THEff.State.Strict: effState :: EffClass State' v e => State' v r -> Eff e r
+ Control.THEff.State.Strict: get :: EffClass State' v e => Eff e v
+ Control.THEff.State.Strict: modify :: EffClass State' v e => (v -> v) -> Eff e ()
+ Control.THEff.State.Strict: put :: EffClass State' v e => v -> Eff e ()
+ Control.THEff.State.Strict: runEffState :: Monad m => (u t r -> (r -> m (StateResT z v)) -> m (StateResT z v)) -> (State m1 e o w a -> r) -> (r -> State t r u v z) -> StateArgT v -> Eff r a -> m (StateResT z v)
+ Control.THEff.State.Strict: stateOnly :: (t -> e -> (r, v)) -> t -> e -> v
+ Control.THEff.State.Strict: type StateArgT v = v
+ Control.THEff.State.Strict: type StateResT r v = (r, v)
+ Control.THEff.State.Strict: withoutState :: (t -> e -> (r, v)) -> t -> e -> r
+ Control.THEff.Writer.Strict: WriterAction :: (Writer' v e) -> Writer e o v a
+ Control.THEff.Writer.Strict: WriterOuter :: (o m e) -> Writer e o v a
+ Control.THEff.Writer.Strict: WriterResult :: a -> Writer e o v a
+ Control.THEff.Writer.Strict: data Writer (m :: * -> *) e o v a
+ Control.THEff.Writer.Strict: data Writer' v e
+ Control.THEff.Writer.Strict: effWriter :: EffClass Writer' v e => Writer' v r -> Eff e r
+ Control.THEff.Writer.Strict: runEffWriter :: (Monad m, Monoid v) => (u t r -> (r -> m (WriterResT z v)) -> m (WriterResT z v)) -> (Writer m1 e o w a -> r) -> (r -> Writer t r u v z) -> Eff r a -> m (WriterResT z v)
+ Control.THEff.Writer.Strict: tell :: EffClass Writer' v e => v -> Eff e ()
+ Control.THEff.Writer.Strict: type WriterResT r v = (r, v)

Files

THEff.cabal view
@@ -1,81 +1,85 @@-name:                THEff
-version:             0.1.0.1
-synopsis:            TH implementation of effects. 
-license:             BSD3
-license-file:        LICENSE
-author:              Kolodezny Diver
-maintainer:          kolodeznydiver@gmail.com
-category:            Control, Effect, TH 
-build-type:          Simple
-cabal-version:       >=1.10
-description:    
-  This package implements effects, as alternative to monad
-  transformers. Actually, the effects themselves are created without 
-  the use of TH, but the binding of nested effects described by 
-  mkEff splice. For example.
-  .
-  > mkEff "MyReader"    ''Reader    ''Int       ''Lift
-  > mkEff "SomeState"   ''State     ''Bool      ''MyReader
-  > mkEff "OtherRdr"    ''Reader    ''Float     ''SomeState
-  > 
-  > main:: IO ()
-  > main = do
-  >     r <- runMyReader  100 
-  >        $ runSomeState False
-  >        $ runOtherRdr  pi  $ do
-  >             i :: Int   <- ask                    -- MyReader 
-  >             f :: Float <- ask                    -- OtherRdr
-  >             b <- get                             -- SomeState
-  >             put $ not b                          -- SomeState 
-  >             lift $ putStrLn "print from effect!" -- Lift  
-  >             return $ show $ fromIntegral i * f 
-  >     print r
-  .
-  For more information about extensible effects , see the original paper at
-  <http://okmij.org/ftp/Haskell/extensible/exteff.pdf>.
-  But, this package is significantly different from the original.
-  It uses a chains of ordinary GADTs created by TH. 
-  No Typeable, unsafe... , ExistentialQuantification ...
-
-extra-source-files:    samples/*.hs
-  
-Source-repository head
-    type:               git
-    location:           https://github.com/KolodeznyDiver/THEff.git
-    
-library
-  ghc-options:         -Wall 
-  exposed-modules:     Control.THEff
-                       Control.THEff.Reader
-                       Control.THEff.State
-                       Control.THEff.Exception
-                       Control.THEff.Catch
-                       Control.THEff.Writer
-                       Control.THEff.Fresh
-                       Control.THEff.Validator
-  
-  -- Modules included in this library but not exported.
-  other-modules:       Control.THEff.TH.Internal
-  
-  -- LANGUAGE extensions used by modules in this package.
-  other-extensions:    KindSignatures
-                       , FlexibleInstances
-                       , FlexibleContexts
-                       , MultiParamTypeClasses
-                       , TemplateHaskell
-                       , ViewPatterns
-                       , RecordWildCards
-                       , ScopedTypeVariables
-                       , RankNTypes
-                       , GADTs
-  
-  -- Other library packages from which modules are imported.
-  build-depends:       base >=4.8 && <4.9
-                      ,template-haskell >=2.4 && <2.11
-  
-  -- Directories containing source files.
-  hs-source-dirs:      src
-  
-  -- Base language which the package is written in.
-  default-language:    Haskell2010
+name:                THEff+version:             0.1.1.0+synopsis:            TH implementation of effects. +license:             BSD3+license-file:        LICENSE+author:              Kolodezny Diver+maintainer:          kolodeznydiver@gmail.com+category:            Control, Effect, TH +build-type:          Simple+cabal-version:       >=1.10+description:    +  This package implements effects, as alternative to monad+  transformers. Actually, the effects themselves are created without +  the use of TH, but the binding of nested effects described by +  mkEff splice. For example.+  .+  > mkEff "MyReader"    ''Reader    ''Int       ''Lift+  > mkEff "SomeState"   ''State     ''Bool      ''MyReader+  > mkEff "OtherRdr"    ''Reader    ''Float     ''SomeState+  > +  > main:: IO ()+  > main = do+  >     r <- runMyReader  100 +  >        $ runSomeState False+  >        $ runOtherRdr  pi  $ do+  >             i :: Int   <- ask                    -- MyReader +  >             f :: Float <- ask                    -- OtherRdr+  >             b <- get                             -- SomeState+  >             put $ not b                          -- SomeState +  >             lift $ putStrLn "print from effect!" -- Lift  +  >             return $ show $ fromIntegral i * f +  >     print r+  .+  For more information about extensible effects , see the original paper at+  <http://okmij.org/ftp/Haskell/extensible/exteff.pdf>.+  But, this package is significantly different from the original.+  It uses a chains of ordinary GADTs created by TH. +  No Typeable, unsafe... , ExistentialQuantification ...++extra-source-files:    samples/*.hs+  +Source-repository head+    type:               git+    location:           https://github.com/KolodeznyDiver/THEff.git+    +library+  ghc-options:         -Wall +  exposed-modules:     Control.THEff+                       Control.THEff.Reader+                       Control.THEff.State+                       Control.THEff.Exception+                       Control.THEff.Catch+                       Control.THEff.Writer+                       Control.THEff.Fresh+                       Control.THEff.Validator+                       Control.THEff.Writer.Strict+                       Control.THEff.Reader.Strict+                       Control.THEff.State.Strict +  +  -- Modules included in this library but not exported.+  other-modules:       Control.THEff.TH.Internal+  +  -- LANGUAGE extensions used by modules in this package.+  other-extensions:    KindSignatures+                       , FlexibleInstances+                       , FlexibleContexts+                       , MultiParamTypeClasses+                       , TemplateHaskell+                       , ViewPatterns+                       , RecordWildCards+                       , ScopedTypeVariables+                       , RankNTypes+                       , GADTs+                       , BangPatterns+  +  -- Other library packages from which modules are imported.+  build-depends:       base >=4.8 && <4.9+                      ,template-haskell >=2.4 && <2.11+  +  -- Directories containing source files.+  hs-source-dirs:      src+  +  -- Base language which the package is written in.+  default-language:    Haskell2010   
samples/SampleAll.hs view
@@ -21,8 +21,8 @@ mkEff "MyReader"    ''Reader    ''Int       ''Lift mkEff "SomeState"   ''State     ''Bool      ''MyReader mkEff "OtherRdr"    ''Reader    ''Float     ''SomeState-mkEff "MyWriter"     ''Writer   ''String    ''OtherRdr-mkEff "MyException" ''Except    ''String   ''MyWriter+mkEff "MyWriter"    ''Writer    ''String    ''OtherRdr+mkEff "MyException" ''Except    ''String    ''MyWriter mkEff "MyCatch"     ''Catch     ''Int       ''MyException mkEff "UnicalChar"  ''Fresh     ''Char      ''MyCatch mkEff "MyVldtr"     ''Validator ''Float     ''UnicalChar
src/Control/THEff.hs view
@@ -106,7 +106,7 @@ newtype NoEff (m:: * -> *) a = NoEff { unNoEff :: a}  -- | This function is used in the 'mkEff' generated runEEEE... functions. --- > @effNoEff _ = error "THEff: Attempting to call the effect NoEff that does not have any actions!"@+-- @effNoEff _ = error "THEff: Attempting to call the effect NoEff that does not have any actions!"@ effNoEff :: a -> b effNoEff _ = error "THEff: Attempting to call the effect NoEff that does not have any actions!" 
src/Control/THEff/Reader.hs view
@@ -7,6 +7,9 @@ module Control.THEff.Reader (                       -- * Overview  -- |+-- This version builds its output lazily; for a strict version with+-- the same interface, see "Control.THEff.Reader.Strict".+-- -- > {-# LANGUAGE KindSignatures #-} -- > {-# LANGUAGE FlexibleInstances #-} -- > {-# LANGUAGE MultiParamTypeClasses #-}
+ src/Control/THEff/Reader/Strict.hs view
@@ -0,0 +1,96 @@+{-# OPTIONS_HADDOCK show-extensions #-}++{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BangPatterns #-}++module Control.THEff.Reader.Strict (+                      -- * Overview +-- |+-- This version builds its output strictly; for a lazy version with+-- the same interface, see "Control.THEff.Reader".+--+-- > {-# LANGUAGE KindSignatures #-}+-- > {-# LANGUAGE FlexibleInstances #-}+-- > {-# LANGUAGE MultiParamTypeClasses #-}+-- > {-# LANGUAGE TemplateHaskell #-}+-- > +-- > import Control.THEff+-- > import Control.THEff.Reader.Strict+-- > +-- > mkEff "CharReader"   ''Reader    ''Char       ''NoEff+-- > mkEff "StrReader"    ''Reader    ''String     ''CharReader+-- > +-- > main:: IO ()+-- > main = putStrLn $ runCharReader 'T' $ runStrReader "est" $ do+-- >             c <- ask+-- >             s <- ask+-- >             return $ c:s+-- +-- __/Output :/__ "Test"++                      -- * Types and functions used in mkEff+                              Reader' +                            , Reader(..)+                            , ReaderArgT+                            , ReaderResT+                            , effReader+                            , runEffReader+                      -- * Functions that use this effect                         +                            , ask+                            , asks+                            ) where++import Control.THEff++-- | Actually, the effect type+--  - __/v/__ - Type - the parameter of the effect.+--  - __/e/__ - mkEff generated type.+newtype Reader' v e = Reader' (v -> e)++-- | Type implements link in the chain of effects.+--   Constructors must be named __/{EffectName}{Outer|WriterAction|WriterResult}/__+--   and have a specified types of fields.+-- - __/m/__ - Or Monad (if use the 'Lift') or phantom type - stub (if used 'NoEff').+-- - __/o/__ - Type of outer effect.+-- - __/a/__ - The result of mkEff generated runEEEE... function.+data Reader (m:: * -> *) e o v a = ReaderOuter (o m e)+                                 | ReaderAction (Reader' v e)+                                 | ReaderResult a ++-- | Type of fourth argument of runEffReader and first argument of runEEEE. +type ReaderArgT v = v++-- | Result type of runEEEE.  +type ReaderResT r = r++-- | This function is used in the 'mkEff' generated runEEEE functions and typically +-- in effect action functions. Calling the effect action.+effReader:: EffClass Reader' v e => Reader' v r -> Eff e r+effReader (Reader' g) = effAction $ \k -> Reader' (k . g)++-- | The main function of the effect implementing. +-- This function is used in the 'mkEff' generated runEEEE functions. +runEffReader :: forall (t :: * -> *) (u :: (* -> *) -> * -> *) (m :: * -> *) a v +            (m1 :: * -> *) e (o :: (* -> *) -> * -> *) w a1 r. Monad m =>+    (u t r -> (r -> m (ReaderResT a)) -> m (ReaderResT a)) -- ^ The outer effect function+ -> (Reader m1 e o w a1 -> r) -- ^ The chain of effects link wrapper.+ -> (r -> Reader t r u v a)  -- ^ The chain of effects link unwrapper.+ -> ReaderArgT v -- ^ The initial value of argument of effect.+ -> Eff r a1+ -> m (ReaderResT a)+runEffReader outer to un !v m = loop $ runEff m (to . ReaderResult)+    where+        loop = select . un+        select (ReaderOuter f)  = outer f loop+        select (ReaderAction (Reader' g)) = loop $ g v+        select (ReaderResult r) = return r++-- | Get reader value+ask :: EffClass Reader' v e => Eff e v+ask = effReader $ Reader' id++-- | Get and convert the value of the reader+asks :: EffClass Reader' r e => (r -> v) -> Eff e v+asks f = effReader $ Reader' f
src/Control/THEff/State.hs view
@@ -7,6 +7,9 @@ module Control.THEff.State (                       -- * Overview  -- |+-- This version builds its output lazily; for a strict version with+-- the same interface, see "Control.THEff.State.Strict".+-- -- > {-# LANGUAGE KindSignatures #-} -- > {-# LANGUAGE FlexibleInstances #-} -- > {-# LANGUAGE MultiParamTypeClasses #-}
+ src/Control/THEff/State/Strict.hs view
@@ -0,0 +1,122 @@+{-# OPTIONS_HADDOCK show-extensions #-}++{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BangPatterns #-}++module Control.THEff.State.Strict (+                      -- * Overview +-- |+-- This version builds its output strictly; for a lazy version with+-- the same interface, see "Control.THEff.State".+--+-- > {-# LANGUAGE KindSignatures #-}+-- > {-# LANGUAGE FlexibleInstances #-}+-- > {-# LANGUAGE MultiParamTypeClasses #-}+-- > {-# LANGUAGE TemplateHaskell #-}+-- > +-- > import Control.THEff+-- > import Control.THEff.State.Strict+-- > +-- > mkEff "Example1"   ''State     ''Int      ''NoEff+-- > mkEff "Example2"   ''State     ''Float    ''Example1+-- > +-- > main:: IO ()+-- > main = print $ runExample1 123 +-- >              $ runExample2 pi $ do+-- >                     i <- get+-- >                     modify ((1 :: Int) +)+-- >                     put $ i * (2 :: Float)+-- >                     return  $ show i +-- +-- __/Output :/__ (("3.1415927",6.2831855),124)++                      -- * Types and functions used in mkEff+                            State'+                          , State(..) +                          , StateArgT+                          , StateResT+                          , effState+                          , runEffState +                      -- * Functions that use this effect                         +                          , get+                          , put+                          , modify+                      -- * Helper functions+                          , stateOnly+                          , withoutState+                          ) where++import Control.THEff++-- | Actually, the effect type+--  - __/v/__ - Type - the parameter of the effect.+--  - __/e/__ - mkEff generated type.+data State' v e = State' (v -> v) (v -> e)  ++-- | Type implements link in the chain of effects.+--   Constructors must be named __/{EffectName}{Outer|WriterAction|WriterResult}/__+--   and have a specified types of fields.+-- - __/m/__ - Or Monad (if use the 'Lift') or phantom type - stub (if used 'NoEff').+-- - __/o/__ - Type of outer effect.+-- - __/a/__ - The result of mkEff generated runEEEE... function.+data State (m:: * -> *) e o v a = StateOuter (o m e)+                                | StateAction (State' v e)    +                                | StateResult a++-- | Type of fourth argument of runEffState and first argument of runEEEE. +type StateArgT v = v++-- | Result type of runEEEE.  +type StateResT r v = (r, v)++-- | This function is used in the 'mkEff' generated runEEEE functions and typically +-- in effect action functions. Calling the effect action.+effState:: EffClass State' v e => State' v r -> Eff e r+effState (State' f g) = effAction $ \k -> State' f (k . g)++-- | The main function of the effect implementing. +-- This function is used in the 'mkEff' generated runEEEE functions. +runEffState :: forall (t :: * -> *) (u :: (* -> *) -> * -> *) (m :: * -> *) +             z v (m1 :: * -> *) e (o :: (* -> *) -> * -> *) w a r. Monad m =>+    (u t r -> (r -> m (StateResT z v)) -> m (StateResT z v)) -- ^ The outer effect function+ -> (State m1 e o w a -> r) -- ^ The chain of effects link wrapper.+ -> (r -> State t r u v z)  -- ^ The chain of effects link unwrapper.+ -> StateArgT v -- ^ The initial value of argument of effect.+ -> Eff r a+ -> m  (StateResT z v)+runEffState outer to un v m = loop v $ runEff m (to . StateResult)+  where +    loop !s = select . un where+        select (StateOuter f)  = outer f (loop s)+        select (StateAction (State' t k)) = let s' = t s in loop s' (k s')+        select (StateResult r) = return (r,s)++-- | Get state value+get :: EffClass State' v e => Eff e v+get = effState $ State' id id+    +-- | Put state value+put :: EffClass State' v e => v -> Eff e ()+put !s = modify $ const s+    +-- | Modify state value+modify :: EffClass State' v e => (v -> v) -> Eff e ()+modify f = effState $ State' f (const ())+ +-- | @ stateOnly runExample1 123 === snd (runExample1 123) @+stateOnly :: forall v e r t. +    (t -> e -> (r, v)) -- ^ State effect runEEEE function+ -> t -- ^ The initial value of argument of effect. + -> e -- ^ Eff (MyState m ...) ... + -> v+stateOnly f v = snd . (f v)++-- | @ withoutState runExample1 123 === fst (runExample1 123) @+withoutState :: forall v e r t. +    (t -> e -> (r, v)) -- ^ State effect runEEEE function+ -> t -- ^ The initial value of argument of effect. + -> e -- ^ Eff (MyState m ...) ... + -> r+withoutState f v = fst . (f v)
src/Control/THEff/TH/Internal.hs view
@@ -1,7 +1,5 @@ {-# OPTIONS_HADDOCK show-extensions #-} -{-# OPTIONS_HADDOCK show-extensions #-}- {-# LANGUAGE  TemplateHaskell, ViewPatterns, RecordWildCards #-} module Control.THEff.TH.Internal(mkEff) where 
src/Control/THEff/Writer.hs view
@@ -7,6 +7,9 @@ module Control.THEff.Writer (                       -- * Overview  -- |+-- This version builds its output lazily; for a strict version with+-- the same interface, see "Control.THEff.Writer.Strict".+-- -- > {-# LANGUAGE KindSignatures #-} -- > {-# LANGUAGE FlexibleInstances #-} -- > {-# LANGUAGE MultiParamTypeClasses #-}
+ src/Control/THEff/Writer/Strict.hs view
@@ -0,0 +1,101 @@+{-# OPTIONS_HADDOCK show-extensions #-}++{-# LANGUAGE KindSignatures #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE BangPatterns #-}++module Control.THEff.Writer.Strict (+                      -- * Overview +-- |+-- This version builds its output strictly; for a lazy version with+-- the same interface, see "Control.THEff.Writer".+--+-- > {-# LANGUAGE KindSignatures #-}+-- > {-# LANGUAGE FlexibleInstances #-}+-- > {-# LANGUAGE MultiParamTypeClasses #-}+-- > {-# LANGUAGE TemplateHaskell #-}+-- > +-- > import Control.THEff+-- > import Control.THEff.Writer.Strict+-- > import Control.Monad(forM_) +-- > import Data.Monoid+-- > +-- > type IntAccum = Sum Int+-- > +-- > mkEff "StrWriter"   ''Writer   ''String    ''NoEff+-- > mkEff "IntWriter"   ''Writer   ''IntAccum  ''StrWriter+-- > +-- > main:: IO ()+-- > main = putStrLn $ uncurry (flip (++)) $ runStrWriter $ do+-- >             tell "Result"+-- >             (r, Sum v) <- runIntWriter $ do+-- >                 tell "="+-- >                 forM_ [1::Int .. 10]+-- >                     (tell . Sum)+-- >                 return (pi :: Float)+-- >             return $ show $ r * fromIntegral v+-- +-- __/Output :/__ Result=172.7876+--+-- Note that for the effect `Writer' `mkEff' generates unary function runEEEE. `mkEff' chooses +-- generation unary or binary function runEEEE based on number of arguments of  effect function. +-- E.g. runEffWriter.++                      -- * Types and functions used in mkEff+                            Writer'+                          , Writer(..) +                          , WriterResT+                          , effWriter+                          , runEffWriter +                      -- * Functions that use this effect                         +                          , tell+                          ) where++import Control.THEff+import Data.Monoid++-- | Actually, the effect type+--  - __/v/__ - Type - the parameter of the effect.+--  - __/e/__ - mkEff generated type.+data Writer' v e = Writer' !v (() -> e)  ++-- | Type implements link in the chain of effects.+--   Constructors must be named __/{EffectName}{Outer|WriterAction|WriterResult}/__+--   and have a specified types of fields.+-- - __/m/__ - Or Monad (if use the 'Lift') or phantom type - stub (if used 'NoEff').+-- - __/o/__ - Type of outer effect.+-- - __/a/__ - The result of mkEff generated runEEEE... function.+data Writer (m:: * -> *) e o v a = WriterOuter (o m e)+                                 | WriterAction (Writer' v e)    +                                 | WriterResult a++-- | Result type of runEEEE.  +type WriterResT r v = (r, v)++-- | This function is used in the 'mkEff' generated runEEEE functions and typically +-- in effect action functions. Calling the effect action.+effWriter:: EffClass Writer' v e => Writer' v r -> Eff e r+effWriter (Writer' v g) = effAction $ \k -> Writer' v (k . g)+ +-- | The main function of the effect implementing. +-- This function is used in the 'mkEff' generated runEEEE functions. +runEffWriter :: forall (t :: * -> *) (u :: (* -> *) -> * -> *) (m :: * -> *) +             z v (m1 :: * -> *) e (o :: (* -> *) -> * -> *) w a r. (Monad m, Monoid v) =>+    (u t r -> (r -> m (WriterResT z v)) -> m (WriterResT z v)) -- ^ The outer effect function+ -> (Writer m1 e o w a -> r) -- ^ The chain of effects link wrapper.+ -> (r -> Writer t r u v z)  -- ^ The chain of effects link unwrapper.+--             -> WriterArgT v  -- unused argument!+ -> Eff r a+ -> m  (WriterResT z v)+runEffWriter outer to un m = loop mempty $ runEff m (to . WriterResult)+  where +    loop !s = select . un where+        select (WriterOuter g)  = outer g (loop s)+        select (WriterAction (Writer' v k)) = let s' = s `mappend` v -- (f v)+                                              in loop s' (k ())+        select (WriterResult r) = return (r,s)++-- | Add value to monoid. +tell :: EffClass Writer' v e => v -> Eff e ()+tell !v = effWriter $ Writer' v (const ())