module Acquire.Acquire where import Acquire.Prelude {-| Implementation of http://www.haskellforall.com/2013/06/the-resource-applicative.html -} newtype Acquire resource = Acquire (IO (resource, IO ())) instance Functor Acquire where fmap f (Acquire io) = Acquire $ do (resource, release) <- io return (f resource, release) instance Applicative Acquire where pure resource = Acquire (pure (resource, pure ())) Acquire io1 <*> Acquire io2 = Acquire $ do (f, release1) <- io1 (x, release2) <- onException io2 release1 return (f x, release2 >> release1) instance Monad Acquire where return = pure (>>=) (Acquire io1) k2 = Acquire $ do (resource1, release1) <- io1 (resource2, release2) <- case k2 resource1 of Acquire io2 -> onException io2 release1 return (resource2, release2 >> release1) instance MonadIO Acquire where liftIO io = Acquire (fmap (, return ()) io)