packages feed

io-classes 1.4.0.0 → 1.4.1.0

raw patch · 3 files changed

+44/−10 lines, 3 filesdep +primitive

Dependencies added: primitive

Files

CHANGELOG.md view
@@ -1,5 +1,13 @@ # Revsion history of io-classes +## 1.4.1.0++### Non-breaking changes++* New dependency on `primitive` package+* New `stToIO` in `MonadST`, which is simpler to use than the existing+  `withLiftST`, and depends on the `primitive` package's `PrimState` (#141).+ ## 1.4.0.0  ### Breaking changes
io-classes.cabal view
@@ -1,6 +1,6 @@ cabal-version:       3.0 name:                io-classes-version:             1.4.0.0+version:             1.4.1.0 synopsis:            Type classes for concurrency with STM, ST and timing description:   IO Monad class hierarchy compatible with@@ -98,6 +98,7 @@                        async >=2.1,                        bytestring,                        mtl   >=2.2 && <2.4,+                       primitive >= 0.7 && <0.10,                        stm   >=2.5 && <2.6,                        time  >=1.9.1 && <1.13 
src/Control/Monad/Class/MonadST.hs view
@@ -1,35 +1,60 @@-{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE InstanceSigs        #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE ScopedTypeVariables #-} module Control.Monad.Class.MonadST (MonadST (..)) where  import Control.Monad.Reader -import Control.Monad.ST (ST, stToIO)+import Control.Monad.Primitive+import Control.Monad.ST as ST (ST, stToIO)   -- | This class is for abstracting over 'stToIO' which allows running 'ST' -- actions in 'IO'. In this case it is to allow running 'ST' actions within -- another monad @m@. ----- The type of 'stToIO' is:+-- The normal type of 'stToIO' is: ----- > stToIO : ST RealWorld a -> IO a+-- > stToIO :: ST RealWorld a -> IO a ----- Abstracting over this is tricky because we need to not care about both--- the @IO@, and also the @RealWorld@.+-- We have two approaches to abstracting over this, a new and an older+-- (deprecated) method. The new method borrows the @primitive@ package's+-- 'PrimMonad' and 'PrimState' type family. This gives us: ----- A solution is to write an action that is given the @liftST@ as an argument+-- > stToIO :: ST (PrimState m) a -> m a+--+-- Which for 'IO' is exactly the same as above. For 'ST' it is identity, while+-- for @IOSim@ it is+--+-- > stToIO :: ST s a -> IOSim s a+--+-- The older (deprecated) method is tricky because we need to not care about+-- both the @IO@, and also the @RealWorld@, and it does so avoiding mentioning+-- any @s@ type (which is what the 'PrimState' type family gives access to).+-- The solution is to write an action that is given the @liftST@ as an argument -- and where that action itself is polymorphic in the @s@ parameter. This -- allows us to instantiate it with @RealWorld@ in the @IO@ case, and the local -- @s@ in a case where we are embedding into another @ST@ action. -- class Monad m => MonadST m where+  -- | @since 1.4.1.0+  stToIO :: ST (PrimState m) a -> m a++  -- | Deprecated. Use 'stToIO' instead.   withLiftST :: (forall s. (forall a. ST s a -> m a) -> b) -> b +{-# DEPRECATED withLiftST "Use the simpler 'stToIO' instead." #-}+ instance MonadST IO where-  withLiftST = \f -> f stToIO+  stToIO = stToPrim+  withLiftST = \f -> f ST.stToIO  instance MonadST (ST s) where+  stToIO = stToPrim   withLiftST = \f -> f id -instance MonadST m => MonadST (ReaderT r m) where+instance (MonadST m, PrimMonad m) => MonadST (ReaderT r m) where+  stToIO :: ST (PrimState m) a -> ReaderT r m a+  stToIO f = lift (stToPrim f)+   withLiftST f = withLiftST $ \g -> f (lift . g)