{-# LANGUAGE Safe #-}
module Text.Chatty.Finalizer where
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import System.IO
class Monad m => ChFinalizer m where
mqfh :: Handle -> m ()
mqfhs :: [Handle] -> m ()
mqfhs = (Handle -> m () -> m ()) -> m () -> [Handle] -> m ()
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (m () -> m () -> m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>) (m () -> m () -> m ())
-> (Handle -> m ()) -> Handle -> m () -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handle -> m ()
forall (m :: * -> *). ChFinalizer m => Handle -> m ()
mqfh) (() -> m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())
mfin :: m ()
newtype HandleCloserT m a = HandleCloser { HandleCloserT m a -> [Handle] -> m (a, [Handle])
runHandleCloserT :: [Handle] -> m (a,[Handle]) }
instance Monad m => Monad (HandleCloserT m) where
return :: a -> HandleCloserT m a
return a
a = ([Handle] -> m (a, [Handle])) -> HandleCloserT m a
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m (a, [Handle])) -> HandleCloserT m a)
-> ([Handle] -> m (a, [Handle])) -> HandleCloserT m a
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> (a, [Handle]) -> m (a, [Handle])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[Handle]
hs)
(HandleCloser [Handle] -> m (a, [Handle])
m) >>= :: HandleCloserT m a -> (a -> HandleCloserT m b) -> HandleCloserT m b
>>= a -> HandleCloserT m b
f = ([Handle] -> m (b, [Handle])) -> HandleCloserT m b
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m (b, [Handle])) -> HandleCloserT m b)
-> ([Handle] -> m (b, [Handle])) -> HandleCloserT m b
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> do (a
a,[Handle]
hs') <- [Handle] -> m (a, [Handle])
m [Handle]
hs; HandleCloserT m b -> [Handle] -> m (b, [Handle])
forall (m :: * -> *) a.
HandleCloserT m a -> [Handle] -> m (a, [Handle])
runHandleCloserT (a -> HandleCloserT m b
f a
a) [Handle]
hs'
instance MonadTrans HandleCloserT where
lift :: m a -> HandleCloserT m a
lift m a
m = ([Handle] -> m (a, [Handle])) -> HandleCloserT m a
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m (a, [Handle])) -> HandleCloserT m a)
-> ([Handle] -> m (a, [Handle])) -> HandleCloserT m a
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> do a
a <- m a
m; (a, [Handle]) -> m (a, [Handle])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a,[Handle]
hs)
instance Monad m => Functor (HandleCloserT m) where
fmap :: (a -> b) -> HandleCloserT m a -> HandleCloserT m b
fmap a -> b
f HandleCloserT m a
a = ([Handle] -> m (b, [Handle])) -> HandleCloserT m b
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m (b, [Handle])) -> HandleCloserT m b)
-> ([Handle] -> m (b, [Handle])) -> HandleCloserT m b
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> do (a
a',[Handle]
hs') <- HandleCloserT m a -> [Handle] -> m (a, [Handle])
forall (m :: * -> *) a.
HandleCloserT m a -> [Handle] -> m (a, [Handle])
runHandleCloserT HandleCloserT m a
a [Handle]
hs; (b, [Handle]) -> m (b, [Handle])
forall (m :: * -> *) a. Monad m => a -> m a
return (a -> b
f a
a',[Handle]
hs')
instance Monad m => Applicative (HandleCloserT m) where
<*> :: HandleCloserT m (a -> b) -> HandleCloserT m a -> HandleCloserT m b
(<*>) = HandleCloserT m (a -> b) -> HandleCloserT m a -> HandleCloserT m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
pure :: a -> HandleCloserT m a
pure = a -> HandleCloserT m a
forall (m :: * -> *) a. Monad m => a -> m a
return
instance MonadIO m => MonadIO (HandleCloserT m) where
liftIO :: IO a -> HandleCloserT m a
liftIO = m a -> HandleCloserT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> HandleCloserT m a)
-> (IO a -> m a) -> IO a -> HandleCloserT m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
instance MonadIO m => ChFinalizer (HandleCloserT m) where
mqfh :: Handle -> HandleCloserT m ()
mqfh Handle
h = ([Handle] -> m ((), [Handle])) -> HandleCloserT m ()
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m ((), [Handle])) -> HandleCloserT m ())
-> ([Handle] -> m ((), [Handle])) -> HandleCloserT m ()
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> ((), [Handle]) -> m ((), [Handle])
forall (m :: * -> *) a. Monad m => a -> m a
return ((),Handle
hHandle -> [Handle] -> [Handle]
forall a. a -> [a] -> [a]
:[Handle]
hs)
mfin :: HandleCloserT m ()
mfin = ([Handle] -> m ((), [Handle])) -> HandleCloserT m ()
forall (m :: * -> *) a.
([Handle] -> m (a, [Handle])) -> HandleCloserT m a
HandleCloser (([Handle] -> m ((), [Handle])) -> HandleCloserT m ())
-> ([Handle] -> m ((), [Handle])) -> HandleCloserT m ()
forall a b. (a -> b) -> a -> b
$ \[Handle]
hs -> do
[m ()] -> m ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ ([m ()] -> m ()) -> [m ()] -> m ()
forall a b. (a -> b) -> a -> b
$ (Handle -> m ()) -> [Handle] -> [m ()]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO(IO () -> m ()) -> (Handle -> IO ()) -> Handle -> m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Handle -> IO ()
hClose) [Handle]
hs
((), [Handle]) -> m ((), [Handle])
forall (m :: * -> *) a. Monad m => a -> m a
return ((),[])
withLazyIO :: (MonadIO m,Functor m) => HandleCloserT m a -> m a
withLazyIO :: HandleCloserT m a -> m a
withLazyIO HandleCloserT m a
m = ((a, [Handle]) -> a) -> m (a, [Handle]) -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a, [Handle]) -> a
forall a b. (a, b) -> a
fst (m (a, [Handle]) -> m a) -> m (a, [Handle]) -> m a
forall a b. (a -> b) -> a -> b
$ HandleCloserT m a -> [Handle] -> m (a, [Handle])
forall (m :: * -> *) a.
HandleCloserT m a -> [Handle] -> m (a, [Handle])
runHandleCloserT (do a
a <- HandleCloserT m a
m; HandleCloserT m ()
forall (m :: * -> *). ChFinalizer m => m ()
mfin; a -> HandleCloserT m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a) []