composewell / streamly

High performance, concurrent functional programming abstractions
https://streamly.composewell.com
Other
861 stars 66 forks source link

Using resourcet with streamly #2701

Open harendra-kumar opened 8 months ago

harendra-kumar commented 8 months ago

resourcet package can be used with streamly-core. With streamly package it would require unliftio instead of monad-control which is only implemented under an experimental flag as of now. Pasting some old comments from another issue below.

runResourceT can be written using MonadBaseControl:

{-# LANGUAGE FlexibleContexts #-}

module RunResourceT where

import Control.Exception (catch, mask, throwIO)
import Control.Monad.IO.Unlift (MonadIO(..), MonadUnliftIO, withRunInIO)
import Control.Monad.Trans.Control (MonadBaseControl, control)
import Control.Monad.Trans.Resource (createInternalState)
import Control.Monad.Trans.Resource.Internal
       (ResourceT(..), stateCleanupChecked)

runResourceT :: MonadBaseControl IO m => ResourceT m a -> m a
runResourceT (ResourceT r) = control $ \run -> do
    istate <- createInternalState
    mask $ \restore -> do
        res <- restore (run (r istate)) `catch` \e -> do
            stateCleanupChecked (Just e) istate
            throwIO e
        stateCleanupChecked Nothing istate
        return res

You can use this function instead of the runResourceT in the resourcet package and use the regular resourcet package. Rest of the functionality you can take from resourcet package. I have not tested it though.