resourcet-effectful 1.0.0.0 → 1.0.1.0
raw patch · 4 files changed
+88/−6 lines, 4 filesdep ~resourcetPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: resourcet
API changes (from Hackage documentation)
+ Effectful.Resource: ReleaseAction :: (forall es. Resource :> es => Eff es ()) -> ReleaseAction
+ Effectful.Resource: ResourceCleanupException :: !Maybe SomeException -> !SomeException -> ![SomeException] -> ResourceCleanupException
+ Effectful.Resource: [rceFirstCleanupException] :: ResourceCleanupException -> !SomeException
+ Effectful.Resource: [rceOriginalException] :: ResourceCleanupException -> !Maybe SomeException
+ Effectful.Resource: [rceOtherCleanupExceptions] :: ResourceCleanupException -> ![SomeException]
+ Effectful.Resource: [runReleaseAction] :: ReleaseAction -> forall es. Resource :> es => Eff es ()
+ Effectful.Resource: allocateEff :: Resource :> es => Eff es a -> (a -> Eff es ()) -> Eff es (ReleaseKey, a)
+ Effectful.Resource: allocateEff_ :: Resource :> es => Eff es a -> Eff es () -> Eff es ReleaseKey
+ Effectful.Resource: data ReleaseKey
+ Effectful.Resource: data ResourceCleanupException
+ Effectful.Resource: newtype ReleaseAction
+ Effectful.Resource: registerEff :: Resource :> es => Eff es () -> Eff es ReleaseKey
+ Effectful.Resource: releaseEff :: Resource :> es => ReleaseKey -> Eff es ()
+ Effectful.Resource: unprotectEff :: Resource :> es => ReleaseKey -> Eff es (Maybe ReleaseAction)
Files
- CHANGELOG.md +6/−1
- README.md +1/−1
- resourcet-effectful.cabal +5/−4
- src/Effectful/Resource.hs +76/−0
CHANGELOG.md view
@@ -1,2 +1,7 @@-# resourcet-effectful-0.1 (2022-07-14)+# resourcet-effectful-1.0.1.0 (2023-11-06)+* Add `allocateEff`, `allocateEff_`, `registerEff`, `releaseEff` and+ `unprotectEff'.+* Re-export `ReleaseKey` and `ResourceCleanupException`.++# resourcet-effectful-1.0.0.0 (2022-07-14) * Initial release.
README.md view
@@ -3,7 +3,7 @@ [](https://github.com/haskell-effectful/resourcet-effectful/actions?query=branch%3Amaster) [](https://hackage.haskell.org/package/resourcet-effectful) [](https://packdeps.haskellers.com/feed?needle=andrzej@rybczak.net)-[](https://www.stackage.org/lts/package/resource-teffectful)+[](https://www.stackage.org/lts/package/resourcet-effectful) [](https://www.stackage.org/nightly/package/resourcet-effectful)
resourcet-effectful.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 build-type: Simple name: resourcet-effectful-version: 1.0.0.0+version: 1.0.1.0 license: BSD-3-Clause license-file: LICENSE category: Control@@ -15,7 +15,8 @@ CHANGELOG.md README.md -tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.3+tested-with: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.7 || ==9.6.3+ || ==9.8.1 bug-reports: https://github.com/haskell-effectful/resourcet-effectful/issues source-repository head@@ -52,8 +53,8 @@ import: language build-depends: base >= 4.13 && < 5- , effectful-core >= 1.0.0.0 && < 1.0.1.0- , resourcet >= 1.2.4.3 && < 1.3+ , effectful-core >= 1.0.0.0 && < 3.0.0.0+ , resourcet >= 1.2.4.3 && < 1.4 hs-source-dirs: src
src/Effectful/Resource.hs view
@@ -9,11 +9,17 @@ , runResource -- * Registering and releasing resources+ , allocateEff+ , allocateEff_+ , registerEff+ , releaseEff , R.allocate , R.allocate_ , R.register , R.release , R.unprotect+ , ReleaseAction(..)+ , unprotectEff -- * Internal state , R.InternalState@@ -21,6 +27,10 @@ , runInternalState , R.createInternalState , R.closeInternalState++ -- * Re-exports+ , R.ReleaseKey+ , R.ResourceCleanupException(..) ) where import Control.Exception@@ -50,6 +60,72 @@ unconsEnv es RI.stateCleanupChecked Nothing istate pure a++----------------------------------------+-- Registering and releasing resources++-- | A variant of 'R.allocate` adjusted to work in the 'Eff' monad.+--+-- /Note:/ the @release@ action will run a cloned environment, so any changes it+-- makes to thread local data will not be visible outside of it.+allocateEff+ :: Resource :> es+ => Eff es a -- ^ allocate+ -> (a -> Eff es ()) -- ^ free resource+ -> Eff es (R.ReleaseKey, a)+allocateEff acquire release = do+ istate <- getInternalState+ unsafeEff $ \es0 -> mask_ $ do+ a <- unEff acquire es0+ -- we need to clone original env for release action+ -- because it will be called when original env already unconsed+ es1 <- cloneEnv es0+ key <- RI.register' istate $ unEff (release a) es1+ pure (key, a)++-- | A variant of 'R.allocate_' adjusted to work in the 'Eff' monad.+--+-- /Note:/ the @release@ action will run a cloned environment, so any changes it+-- makes to thread local data will not be visible outside of it.+allocateEff_+ :: Resource :> es+ => Eff es a -- ^ allocate+ -> Eff es () -- ^ free resource+ -> Eff es R.ReleaseKey+allocateEff_ a = fmap fst . allocateEff a . const++-- | A variant of 'R.register' adjusted to work in the 'Eff' monad.+--+-- /Note:/ the @release@ action will run a cloned environment, so any changes it+-- makes to thread local data will not be visible outside of it.+registerEff :: Resource :> es => Eff es () -> Eff es R.ReleaseKey+registerEff release = do+ istate <- getInternalState+ unsafeEff $ \es0 -> do+ -- we need to clone original env for release action+ -- because it will be called when original env already unconsed+ es1 <- cloneEnv es0+ RI.register' istate $ unEff release es1++-- | A variant of 'R.release' adjusted to work in the 'Eff' monad.+releaseEff :: Resource :> es => R.ReleaseKey -> Eff es ()+releaseEff = unsafeEff_ . R.release++-- | Action for releasing a resource.+newtype ReleaseAction = ReleaseAction+ { runReleaseAction :: forall es. Resource :> es => Eff es ()+ }++-- | A variant of 'R.unprotect' adjusted to work in the 'Eff' monad.+--+-- /Note:/ if the resource was acquired using 'allocateEff', 'allocateEff_' or+-- 'registerEff' then the returned 'ReleaseAction' will run in a clone of the+-- environment it was registered in.+--+-- See the documentation of the aforementioned functions for more information.+unprotectEff :: Resource :> es => R.ReleaseKey -> Eff es (Maybe ReleaseAction)+unprotectEff key = unsafeEff_ $ do+ fmap (\m -> ReleaseAction $ unsafeEff_ m) <$> R.unprotect key ---------------------------------------- -- Internal state