on 8a63c15 help sign in
effectful/src/Effectful/Resource.hs
44 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.Env
21import Effectful.Internal.Has
22import Effectful.Internal.Monad
24-- | Data tag for a resource effect.
25newtype Resource = Resource R.InternalState
27-- | Run the resource effect.
28runResource :: Eff (Resource : es) a -> Eff es a
29runResource (Eff m) = impureEff $ \es0 -> do
30 size0 <- sizeEnv es0
31 istate <- R.createInternalState
32 mask $ \restore -> do
33 es <- unsafeConsEnv (Resource istate) es0
34 a <- restore (m es) `catch` \e -> do
35 _ <- unsafeTrimEnv size0 es
36 RI.stateCleanupChecked (Just e) istate
37 throwIO e
38 _ <- unsafeTrimEnv size0 es
39 RI.stateCleanupChecked Nothing istate
40 pure a
42instance (IOE :> es, Resource :> es) => R.MonadResource (Eff es) where
43 liftResourceT (RI.ResourceT m) = impureEff $ \es -> do
44 getEnv es >>= \(Resource istate) -> m istate