packages feed

monad-unlift 0.1.0.0 → 0.1.0.1

raw patch · 6 files changed

+110/−8 lines, 6 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

Control/Monad/Trans/RWS/Ref.hs view
@@ -11,6 +11,10 @@ -- transformers in the transformers package is that it does not have space -- leaks in the writer component. For more information, see -- <https://mail.haskell.org/pipermail/libraries/2012-October/018599.html>.+--+-- Please see the documentation at+-- <https://www.stackage.org/package/monad-unlift> for more details on using+-- this module. module Control.Monad.Trans.RWS.Ref     ( RWSRefT     , runRWSRefT
Control/Monad/Trans/State/Ref.hs view
@@ -6,6 +6,10 @@ {-# LANGUAGE UndecidableInstances  #-} -- | An implementation of @StateT@ built on top of mutable references, -- providing a proper monad morphism.+--+-- Please see the documentation at+-- <https://www.stackage.org/package/monad-unlift> for more details on using+-- this module. module Control.Monad.Trans.State.Ref     ( StateRefT     , runStateRefT
Control/Monad/Trans/Unlift.hs view
@@ -27,17 +27,13 @@     , MonadBaseControl (..)     ) where -import           Control.Monad               (ap, liftM)+import           Control.Monad               (liftM) import           Control.Monad.Base          (MonadBase (..))-import           Control.Monad.ST            (ST)-import           Control.Monad.STM           (STM) import           Control.Monad.Trans.Class   (MonadTrans (..)) import           Control.Monad.Trans.Control (MonadBaseControl (..),                                               MonadTransControl (..))-import           Control.Monad.Trans.Reader  (ReaderT) import           Data.Constraint             ((:-), (\\)) import           Data.Constraint.Forall      (Forall, inst)-import           Data.Functor.Identity       (Identity)  -- | A function which can move an action down the monad transformer stack, by -- providing any necessary environment to the action.
Control/Monad/Trans/Writer/Ref.hs view
@@ -11,6 +11,10 @@ -- transformers in the transformers package is that it does not have space -- leaks. For more information, see -- <https://mail.haskell.org/pipermail/libraries/2012-October/018599.html>.+--+-- Please see the documentation at+-- <https://www.stackage.org/package/monad-unlift> for more details on using+-- this module. module Control.Monad.Trans.Writer.Ref     ( WriterRefT     , runWriterRefT
README.md view
@@ -1,5 +1,71 @@ ## monad-unlift +Typeclasses for providing for unlifting of monad transformers and stacks, and+concrete implementations of common transformers implementing this type classes.++## Synopsis++```haskell+import Control.Concurrent.Async+import Control.Monad.Trans.Unlift+import Control.Monad.Trans.RWS.Ref+import Control.Monad.IO.Class+import Data.Mutable++-- Some artbirary data type for the MonadReader+data SomeEnv = SomeEnv Int++myFunc :: RWSRefT+    -- The WriterT piece is contained by an IORef+    IORef+    -- For efficiency, we store the state in a primitive+    -- reference for efficiency+    (PRef RealWorld)+    SomeEnv   -- Reader+    [String]  -- Writer+    Int       -- State+    IO+    (String, String)+myFunc = do+    -- Get the unlift function. Due to weaknesses in ImpredicativeTypes, we+    -- need to use a newtype wrapper. You can also use askRunBase.+    --+    -- If you want to just unwrap one transformer layer, use+    -- askUnlift/askRun/Unlift.+    UnliftBase run <- askUnliftBase++    -- Note that we can use unlift to turn our transformer actions into IO+    -- actions. Unlike the standard RWST, actions from separate threads are+    -- both retained due to mutable references.+    --+    -- In real life: you shouldn't rely on this working, as RWST is not thread+    -- safe. This example is provided as a good demonstration of the type level+    -- functionality.+    liftIO $ concurrently (run foo) (run bar)+  where+    foo = do+        tell ["starting foo"]+        modify (+ 1)+        tell ["leaving foo"]+        return "foo is done"+    bar = do+        tell ["starting bar"]+        SomeEnv e <- ask+        modify (+ e)+        tell ["leaving bar"]+        return "bar is done"++main :: IO ()+main = do+    ((w, x), y, z) <- runRWSRefT myFunc (SomeEnv 5) 6+    print w -- foo is done+    print x -- bar is done+    print y -- 12 = 6 + 5 + 1+    print z -- starting and leaving statements, order ambiguous+```++## Overview+ A common pattern is to have some kind of a monad transformer, and want to pass an action into a function that requires actions in a base monad. That sounds a bit abstract, so let's give a concrete example:@@ -65,7 +131,7 @@ ```  Notice how we get `(a, b)` in the return type as desired. There's no need to-unwrap values are deal with context.+unwrap values or deal with context.  ### MonadTransUnlift @@ -74,7 +140,7 @@ later. Some interesting cases in this space are:  * `IdentityT` and things isomorphic to it; in this case, you can think of the environment as being `()`-* Transformers which contain a mutable reference in their environment. This allows them to behave like stateful transformers (e.g., `StateT` or `WriterT`), but still behave the monad morphism laws. (See below for more details.)+* Transformers which contain a mutable reference in their environment. This allows them to behave like stateful transformers (e.g., `StateT` or `WriterT`), but still obey the monad morphism laws. (See below for more details.)  Due to weaknesses in GHC's ImpredicativeTypes, we have a helper datatype to allow for getting polymorphic unlift functions, appropriately named `Unlift`.@@ -138,6 +204,15 @@ package, which allows you to have highly efficient references like `PRef` instead of always using boxed references like `IORef`. +Note that, for generality, the reference transformers take type parameters+indicating which mutable reference type to use. Some examples you may use are:++* `IORef` for boxed references in `IO`+* `STRef s` for boxed references in `ST`+* `PRef RealWorld` for an unboxed reference in `IO`++See the synopsis for a complete example.+ ### conduit  The `transPipe` function in conduit has caused confusion in the past due to its@@ -150,3 +225,22 @@ valid monad morphisms. `HandlerT` is in fact my first example of using the "enviornment holding a mutable reference" technique to overcome exceptions destroying state.++```haskell+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+import Control.Concurrent.Async+import Control.Monad.IO.Class+import Control.Monad.Logger+import Control.Monad.Trans.Unlift++main :: IO ()+main = runStdoutLoggingT foo++foo :: (MonadLogger m, MonadBaseUnlift IO m, MonadIO m) => m ()+foo = do+    run <- askRunBase+    a <- liftIO $ async $ run $ $logDebug "Hello World!"+    liftIO $ wait a+```
monad-unlift.cabal view
@@ -1,5 +1,5 @@ name:                monad-unlift-version:             0.1.0.0+version:             0.1.0.1 synopsis:            Typeclasses for representing monad transformer unlifting description:         See README.md homepage:            https://github.com/fpco/monad-unlift