unliftio-core 0.1.2.0 → 0.2.1.0
raw patch · 3 files changed
Files
- ChangeLog.md +18/−0
- src/Control/Monad/IO/Unlift.hs +58/−35
- unliftio-core.cabal +10/−12
ChangeLog.md view
@@ -1,3 +1,21 @@+# ChangeLog for unliftio-core++## 0.2.1.0++* Added `Control.Monad.IO.Unlift.liftIOOp`++## 0.2.0.2++* Widen `base` upperbound to `< 4.17` to support ghc-9.2.++## 0.2.0.1++* Remove faulty default implementation of `withRunInIO` [#56](https://github.com/fpco/unliftio/issues/56)++## 0.2.0.0++* Move `askUnliftIO` out of class [#55](https://github.com/fpco/unliftio/issues/55)+ ## 0.1.2.0 * Add `wrappedWithRunInIO`.
src/Control/Monad/IO/Unlift.hs view
@@ -4,10 +4,12 @@ module Control.Monad.IO.Unlift ( MonadUnliftIO (..) , UnliftIO (..)+ , askUnliftIO , askRunInIO , withUnliftIO , toIO , wrappedWithRunInIO+ , liftIOOp , MonadIO (..) ) where @@ -34,55 +36,45 @@ -- 'MonadUnliftIO' to 'ReaderT' and 'IdentityT' transformers on top of -- 'IO'. ----- Laws. For any value @u@ returned by 'askUnliftIO', it must meet the+-- Laws. For any function @run@ provided by 'withRunInIO', it must meet the -- monad transformer laws as reformulated for @MonadUnliftIO@: ----- * @unliftIO u . return = return@+-- * @run . return = return@ ----- * @unliftIO u (m >>= f) = unliftIO u m >>= unliftIO u . f@+-- * @run (m >>= f) = run m >>= run . f@ ----- The third is a currently nameless law which ensures that the--- current context is preserved.+-- Instances of @MonadUnliftIO@ must also satisfy the following laws: ----- * @askUnliftIO >>= (\u -> liftIO (unliftIO u m)) = m@+-- [Identity law] @withRunInIO (\\run -> run m) = m@+-- [Inverse law] @withRunInIO (\\_ -> m) = liftIO m@ ----- If you have a name for this, please submit it in a pull request for--- great glory.+-- As an example of an invalid instance, a naive implementation of+-- @MonadUnliftIO (StateT s m)@ might be --+-- @+-- withRunInIO inner =+-- StateT $ \\s ->+-- withRunInIO $ \\run ->+-- inner (run . flip evalStateT s)+-- @+--+-- This breaks the identity law because the inner @run m@ would throw away+-- any state changes in @m@.+-- -- @since 0.1.0.0 class MonadIO m => MonadUnliftIO m where- {-# MINIMAL askUnliftIO | withRunInIO #-}- -- | Capture the current monadic context, providing the ability to- -- run monadic actions in 'IO'.- --- -- See 'UnliftIO' for an explanation of why we need a helper- -- datatype here.- --- -- @since 0.1.0.0- askUnliftIO :: m (UnliftIO m)- askUnliftIO = withRunInIO (\run -> return (UnliftIO run))- {-# INLINE askUnliftIO #-}- -- Would be better, but GHC hates us- -- askUnliftIO :: m (forall a. m a -> IO a)- -- | Convenience function for capturing the monadic context and running an 'IO' -- action with a runner function. The runner function is used to run a monadic -- action @m@ in @IO@. -- -- @since 0.1.0.0- {-# INLINE withRunInIO #-} withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b- withRunInIO inner = askUnliftIO >>= \u -> liftIO (inner (unliftIO u))+ instance MonadUnliftIO IO where- {-# INLINE askUnliftIO #-}- askUnliftIO = return (UnliftIO id) {-# INLINE withRunInIO #-} withRunInIO inner = inner id+ instance MonadUnliftIO m => MonadUnliftIO (ReaderT r m) where- {-# INLINE askUnliftIO #-}- askUnliftIO = ReaderT $ \r ->- withUnliftIO $ \u ->- return (UnliftIO (unliftIO u . flip runReaderT r)) {-# INLINE withRunInIO #-} withRunInIO inner = ReaderT $ \r ->@@ -90,16 +82,30 @@ inner (run . flip runReaderT r) instance MonadUnliftIO m => MonadUnliftIO (IdentityT m) where- {-# INLINE askUnliftIO #-}- askUnliftIO = IdentityT $- withUnliftIO $ \u ->- return (UnliftIO (unliftIO u . runIdentityT)) {-# INLINE withRunInIO #-} withRunInIO inner = IdentityT $ withRunInIO $ \run -> inner (run . runIdentityT) +-- | Capture the current monadic context, providing the ability to+-- run monadic actions in 'IO'.+--+-- See 'UnliftIO' for an explanation of why we need a helper+-- datatype here.+--+-- Prior to version 0.2.0.0 of this library, this was a method in the+-- 'MonadUnliftIO' type class. It was moved out due to+-- <https://github.com/fpco/unliftio/issues/55>.+--+-- @since 0.1.0.0+askUnliftIO :: MonadUnliftIO m => m (UnliftIO m)+askUnliftIO = withRunInIO (\run -> return (UnliftIO run))+{-# INLINE askUnliftIO #-}+-- Would be better, but GHC hates us+-- askUnliftIO :: m (forall a. m a -> IO a)++ -- | Same as 'askUnliftIO', but returns a monomorphic function -- instead of a polymorphic newtype wrapper. If you only need to apply -- the transformation on one concrete type, this function can be more@@ -131,13 +137,16 @@ Useful for the common case where you want to simply delegate to the underlying transformer. +Note: You can derive 'MonadUnliftIO' for newtypes without this helper function+in @unliftio-core@ 0.2.0.0 and later.+ @since 0.1.2.0 ==== __Example__ > newtype AppT m a = AppT { unAppT :: ReaderT Int (ResourceT m) a } > deriving (Functor, Applicative, Monad, MonadIO)-> -- Unfortunately, deriving MonadUnliftIO does not work. >+> -- Same as `deriving newtype (MonadUnliftIO)` > instance MonadUnliftIO m => MonadUnliftIO (AppT m) where > withRunInIO = wrappedWithRunInIO AppT unAppT -}@@ -152,3 +161,17 @@ -> m b wrappedWithRunInIO wrap unwrap inner = wrap $ withRunInIO $ \run -> inner $ run . unwrap++{- | A helper function for lifting @IO a -> IO b@ functions into any @MonadUnliftIO@.++=== __Example__++> liftedTry :: (Exception e, MonadUnliftIO m) => m a -> m (Either e a)+> liftedTry m = liftIOOp Control.Exception.try m++@since 0.2.1.0+-}+liftIOOp :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b+liftIOOp f x = do+ runInIO <- askRunInIO+ liftIO $ f $ runInIO x
unliftio-core.cabal view
@@ -1,35 +1,33 @@-cabal-version: >= 1.10+cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.29.6.+-- This file has been generated from package.yaml by hpack version 0.35.1. -- -- see: https://github.com/sol/hpack------ hash: 9dda29b2ae88c7aba738c44b9efa373de55a416be845a7bf888fc8c108166fed name: unliftio-core-version: 0.1.2.0+version: 0.2.1.0 synopsis: The MonadUnliftIO typeclass for unlifting monads to IO description: Please see the documentation and README at <https://www.stackage.org/package/unliftio-core> category: Control homepage: https://github.com/fpco/unliftio/tree/master/unliftio-core#readme author: Michael Snoyman, Francesco Mazzoli maintainer: michael@snoyman.com-copyright: 2017 FP Complete+copyright: 2017-2020 FP Complete license: MIT license-file: LICENSE build-type: Simple extra-source-files:- ChangeLog.md README.md+ ChangeLog.md library- hs-source-dirs:- src- build-depends:- base >=4.5 && <4.12- , transformers >=0.2 && <0.6 exposed-modules: Control.Monad.IO.Unlift other-modules: Paths_unliftio_core+ hs-source-dirs:+ src+ build-depends:+ base >=4.9 && <4.17+ , transformers >=0.2 && <0.7 default-language: Haskell2010