on 043bffe help sign in
effectful/src/Effectful/Resource.hs
45 lines 1.3 kB history raw
1{-# LANGUAGE UndecidableInstances #-}
2{-# OPTIONS_GHC -Wno-orphans #-}
3-- | Resource management via 'R.MonadResource'.
4module Effectful.Resource
5 ( Resource
6 , runResource
8 -- * Registering and releasing resources
9 , R.allocate
10 , R.allocate_
11 , R.register
12 , R.release
13 , R.unprotect
14 ) where
16import Control.Exception
17import qualified Control.Monad.Trans.Resource as R
18import qualified Control.Monad.Trans.Resource.Internal as RI
20import Effectful.Internal.Effect
21import Effectful.Internal.Env
22import Effectful.Internal.Monad
24-- | Data tag for a resource effect.
25newtype Resource :: Effect where
26 Resource :: R.InternalState -> Resource m r
28-- | Run the resource effect.
29runResource :: IOE :> es => Eff (Resource : es) a -> Eff es a
30runResource m = unsafeEff $ \es0 -> do
31 size0 <- sizeEnv es0
32 istate <- R.createInternalState
33 mask $ \restore -> do
34 es <- unsafeConsEnv (IdE (Resource istate)) noRelinker es0
35 a <- restore (unEff m es) `catch` \e -> do
36 _ <- unsafeTailEnv size0 es
37 RI.stateCleanupChecked (Just e) istate
38 throwIO e
39 _ <- unsafeTailEnv size0 es
40 RI.stateCleanupChecked Nothing istate
41 pure a
43instance (IOE :> es, Resource :> es) => R.MonadResource (Eff es) where
44 liftResourceT (RI.ResourceT m) = unsafeEff $ \es -> do
45 getEnv es >>= \(IdE (Resource istate)) -> m istate