diff --git a/Control/Monad/Trans/Resource.hs b/Control/Monad/Trans/Resource.hs
--- a/Control/Monad/Trans/Resource.hs
+++ b/Control/Monad/Trans/Resource.hs
@@ -58,6 +58,11 @@
     , withInternalState
     , createInternalState
     , closeInternalState
+      -- * Resource
+    , Resource
+    , mkResource
+    , with
+    , allocateResource
     ) where
 
 import qualified Data.IntMap as IntMap
@@ -135,6 +140,13 @@
          -> m (ReleaseKey, a)
 allocate a = liftResourceT . allocateRIO a
 
+-- | Allocate a resource and register an action with the @MonadResource@ to
+-- free the resource.
+--
+-- Since 0.4.10
+allocateResource :: MonadResource m => Resource a -> m (ReleaseKey, a)
+allocateResource = liftResourceT . allocateResourceRIO
+
 -- | Perform asynchronous exception masking.
 --
 -- This is more general then @Control.Exception.mask@, yet more efficient
@@ -148,6 +160,12 @@
 allocateRIO acquire rel = ResourceT $ \istate -> liftIO $ E.mask $ \restore -> do
     a <- restore acquire
     key <- register' istate $ rel a
+    return (key, a)
+
+allocateResourceRIO :: Resource a -> ResourceT IO (ReleaseKey, a)
+allocateResourceRIO (Resource f) = ResourceT $ \istate -> liftIO $ E.mask $ \restore -> do
+    Allocated a free <- f restore
+    key <- register' istate free
     return (key, a)
 
 registerRIO :: IO () -> ResourceT IO ReleaseKey
diff --git a/Control/Monad/Trans/Resource/Internal.hs b/Control/Monad/Trans/Resource/Internal.hs
--- a/Control/Monad/Trans/Resource/Internal.hs
+++ b/Control/Monad/Trans/Resource/Internal.hs
@@ -1,9 +1,11 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE UndecidableInstances #-}
+{-# LANGUAGE RankNTypes #-}
 
 module Control.Monad.Trans.Resource.Internal(
     ExceptionT(..)
@@ -18,13 +20,17 @@
   , stateAlloc
   , stateCleanup
   , transResourceT
+  , Resource (..)
+  , Allocated (..)
+  , with
+  , mkResource
 ) where
 
 import Control.Exception (throw,Exception,SomeException)
 import Control.Applicative (Applicative (..))
 import Control.Monad.Trans.Control
     ( MonadTransControl (..), MonadBaseControl (..)
-    , ComposeSt, defaultLiftBaseWith, defaultRestoreM)
+    , ComposeSt, defaultLiftBaseWith, defaultRestoreM, control)
 import Control.Monad.Base (MonadBase, liftBase)
 import Control.Monad.Trans.Cont     ( ContT  )
 import Control.Monad.Cont.Class   ( MonadCont (..) )
@@ -48,7 +54,7 @@
 import qualified Control.Monad.Trans.Writer.Strict as Strict ( WriterT )
 
 import Control.Monad.IO.Class (MonadIO (..))
-import Control.Monad (liftM)
+import Control.Monad (liftM, ap)
 import qualified Control.Exception as E
 import Control.Monad.ST (ST)
 import Data.IntMap (IntMap)
@@ -418,3 +424,66 @@
     return $! case a of
         Left  l      -> (Left  l, id)
         Right (r, f) -> (Right r, f)
+
+data Allocated a = Allocated !a !(IO ())
+
+-- | A method for allocating a scarce resource, providing the means of freeing
+-- it when no longer needed. This data type provides
+-- @Functor@/@Applicative@/@Monad@ instances for composing different resources
+-- together. You can allocate these resources using either the @bracket@
+-- pattern (via @with@) or using @ResourceT@ (via @allocateResource@).
+--
+-- This concept was originally introduced by Gabriel Gonzalez and described at:
+-- <http://www.haskellforall.com/2013/06/the-resource-applicative.html>. The
+-- implementation in this package is slightly different, due to taking a
+-- different approach to async exception safety.
+--
+-- Since 0.4.10
+newtype Resource a = Resource ((forall b. IO b -> IO b) -> IO (Allocated a))
+    deriving Typeable
+
+instance Functor Resource where
+    fmap = liftM
+instance Applicative Resource where
+    pure = return
+    (<*>) = ap
+
+instance Monad Resource where
+    return a = Resource (\_ -> return (Allocated a (return ())))
+    Resource f >>= g' = Resource $ \restore -> do
+        Allocated x free1 <- f restore
+        let Resource g = g' x
+        Allocated y free2 <- g restore `E.onException` free1
+        return $! Allocated y (free2 `E.finally` free1)
+
+instance MonadIO Resource where
+    liftIO f = Resource $ \restore -> do
+        x <- restore f
+        return $! Allocated x (return ())
+
+instance MonadBase IO Resource where
+    liftBase = liftIO
+
+-- | Create a @Resource@ value using the given allocate and free functions.
+--
+-- Since 0.4.10
+mkResource :: IO a -- ^ allocate the resource
+           -> (a -> IO ()) -- ^ free the resource
+           -> Resource a
+mkResource create free = Resource $ \restore -> do
+    x <- restore create
+    return $! Allocated x (free x)
+
+-- | Allocate the given resource and provide it to the provided function. The
+-- resource will be freed as soon as the inner block is exited, whether
+-- normally or via an exception. This function is similar in function to
+-- @bracket@.
+--
+-- Since 0.4.10
+with :: MonadBaseControl IO m
+     => Resource a
+     -> (a -> m b)
+     -> m b
+with (Resource f) g = control $ \run -> E.mask $ \restore -> do
+    Allocated x free <- f restore
+    run (g x) `E.finally` free
diff --git a/resourcet.cabal b/resourcet.cabal
--- a/resourcet.cabal
+++ b/resourcet.cabal
@@ -1,5 +1,5 @@
 Name:                resourcet
-Version:             0.4.9
+Version:             0.4.10
 Synopsis:            Deterministic allocation and freeing of scarce resources.
 Description:
 	This package was originally included with the conduit package, and has since been split off. For more information, please see <http://www.yesodweb.com/book/conduits>.
