{-# LANGUAGE CPP #-}
{-# LANGUAGE RankNTypes #-}
module Control.Monad.Managed (
Managed,
MonadManaged(..),
managed,
managed_,
with,
runManaged,
module Control.Monad.IO.Class
) where
import Control.Monad.IO.Class (MonadIO(liftIO))
#if MIN_VERSION_base(4,9,0)
import Control.Monad.Fail as MonadFail (MonadFail(..))
#endif
import Control.Monad.Trans.Class (lift)
#if MIN_VERSION_base(4,8,0)
import Control.Applicative (liftA2)
#else
import Control.Applicative
import Data.Monoid (Monoid(..))
#endif
#if !(MIN_VERSION_base(4,11,0))
import Data.Semigroup (Semigroup(..))
#endif
import qualified Control.Monad.Trans.Cont as Cont
#if MIN_VERSION_transformers(0,4,0)
import qualified Control.Monad.Trans.Except as Except
#endif
import qualified Control.Monad.Trans.Identity as Identity
import qualified Control.Monad.Trans.Maybe as Maybe
import qualified Control.Monad.Trans.Reader as Reader
import qualified Control.Monad.Trans.RWS.Lazy as RWS.Lazy
import qualified Control.Monad.Trans.RWS.Strict as RWS.Strict
import qualified Control.Monad.Trans.State.Lazy as State.Lazy
import qualified Control.Monad.Trans.State.Strict as State.Strict
import qualified Control.Monad.Trans.Writer.Lazy as Writer.Lazy
import qualified Control.Monad.Trans.Writer.Strict as Writer.Strict
newtype Managed a = Managed { Managed a -> forall r. (a -> IO r) -> IO r
(>>-) :: forall r . (a -> IO r) -> IO r }
instance Functor Managed where
fmap :: (a -> b) -> Managed a -> Managed b
fmap a -> b
f Managed a
mx = (forall r. (b -> IO r) -> IO r) -> Managed b
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\b -> IO r
return_ ->
Managed a
mx Managed a -> (a -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- \a
x ->
b -> IO r
return_ (a -> b
f a
x) )
instance Applicative Managed where
pure :: a -> Managed a
pure a
r = (forall r. (a -> IO r) -> IO r) -> Managed a
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\a -> IO r
return_ ->
a -> IO r
return_ a
r )
Managed (a -> b)
mf <*> :: Managed (a -> b) -> Managed a -> Managed b
<*> Managed a
mx = (forall r. (b -> IO r) -> IO r) -> Managed b
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\b -> IO r
return_ ->
Managed (a -> b)
mf Managed (a -> b) -> ((a -> b) -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- \a -> b
f ->
Managed a
mx Managed a -> (a -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- \a
x ->
b -> IO r
return_ (a -> b
f a
x) )
instance Monad Managed where
Managed a
ma >>= :: Managed a -> (a -> Managed b) -> Managed b
>>= a -> Managed b
f = (forall r. (b -> IO r) -> IO r) -> Managed b
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\b -> IO r
return_ ->
Managed a
ma Managed a -> (a -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- \a
a ->
a -> Managed b
f a
a Managed b -> (b -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- \b
b ->
b -> IO r
return_ b
b )
instance MonadIO Managed where
liftIO :: IO a -> Managed a
liftIO IO a
m = (forall r. (a -> IO r) -> IO r) -> Managed a
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\a -> IO r
return_ -> do
a
a <- IO a
m
a -> IO r
return_ a
a )
#if MIN_VERSION_base(4,9,0)
instance MonadFail Managed where
fail :: String -> Managed a
fail String
s = (forall r. (a -> IO r) -> IO r) -> Managed a
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed (\a -> IO r
return_ -> do
a
a <- String -> IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
MonadFail.fail String
s
a -> IO r
return_ a
a )
#endif
instance Semigroup a => Semigroup (Managed a) where
<> :: Managed a -> Managed a -> Managed a
(<>) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>)
instance Monoid a => Monoid (Managed a) where
mempty :: Managed a
mempty = a -> Managed a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Monoid a => a
mempty
#if !(MIN_VERSION_base(4,11,0))
mappend = liftA2 mappend
#endif
instance Num a => Num (Managed a) where
fromInteger :: Integer -> Managed a
fromInteger = a -> Managed a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Managed a) -> (Integer -> a) -> Integer -> Managed a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. Num a => Integer -> a
fromInteger
negate :: Managed a -> Managed a
negate = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
negate
abs :: Managed a -> Managed a
abs = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
abs
signum :: Managed a -> Managed a
signum = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
signum
+ :: Managed a -> Managed a -> Managed a
(+) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)
* :: Managed a -> Managed a -> Managed a
(*) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(*)
(-) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (-)
instance Fractional a => Fractional (Managed a) where
fromRational :: Rational -> Managed a
fromRational = a -> Managed a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> Managed a) -> (Rational -> a) -> Rational -> Managed a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. Fractional a => Rational -> a
fromRational
recip :: Managed a -> Managed a
recip = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Fractional a => a -> a
recip
/ :: Managed a -> Managed a -> Managed a
(/) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Fractional a => a -> a -> a
(/)
instance Floating a => Floating (Managed a) where
pi :: Managed a
pi = a -> Managed a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Floating a => a
pi
exp :: Managed a -> Managed a
exp = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
exp
sqrt :: Managed a -> Managed a
sqrt = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sqrt
log :: Managed a -> Managed a
log = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
log
sin :: Managed a -> Managed a
sin = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sin
tan :: Managed a -> Managed a
tan = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
tan
cos :: Managed a -> Managed a
cos = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cos
asin :: Managed a -> Managed a
asin = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sin
atan :: Managed a -> Managed a
atan = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atan
acos :: Managed a -> Managed a
acos = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acos
sinh :: Managed a -> Managed a
sinh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sinh
tanh :: Managed a -> Managed a
tanh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
tanh
cosh :: Managed a -> Managed a
cosh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cosh
asinh :: Managed a -> Managed a
asinh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
asinh
atanh :: Managed a -> Managed a
atanh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atanh
acosh :: Managed a -> Managed a
acosh = (a -> a) -> Managed a -> Managed a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acosh
** :: Managed a -> Managed a -> Managed a
(**) = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Floating a => a -> a -> a
(**)
logBase :: Managed a -> Managed a -> Managed a
logBase = (a -> a -> a) -> Managed a -> Managed a -> Managed a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Floating a => a -> a -> a
logBase
class MonadIO m => MonadManaged m where
using :: Managed a -> m a
instance MonadManaged Managed where
using :: Managed a -> Managed a
using = Managed a -> Managed a
forall a. a -> a
id
instance MonadManaged m => MonadManaged (Cont.ContT r m) where
using :: Managed a -> ContT r m a
using Managed a
m = m a -> ContT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
#if MIN_VERSION_transformers(0,4,0)
instance MonadManaged m => MonadManaged (Except.ExceptT e m) where
using :: Managed a -> ExceptT e m a
using Managed a
m = m a -> ExceptT e m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
#endif
instance MonadManaged m => MonadManaged (Identity.IdentityT m) where
using :: Managed a -> IdentityT m a
using Managed a
m = m a -> IdentityT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance MonadManaged m => MonadManaged (Maybe.MaybeT m) where
using :: Managed a -> MaybeT m a
using Managed a
m = m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance MonadManaged m => MonadManaged (Reader.ReaderT r m) where
using :: Managed a -> ReaderT r m a
using Managed a
m = m a -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance (Monoid w, MonadManaged m) => MonadManaged (RWS.Lazy.RWST r w s m) where
using :: Managed a -> RWST r w s m a
using Managed a
m = m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance (Monoid w, MonadManaged m) => MonadManaged (RWS.Strict.RWST r w s m) where
using :: Managed a -> RWST r w s m a
using Managed a
m = m a -> RWST r w s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance MonadManaged m => MonadManaged (State.Strict.StateT s m) where
using :: Managed a -> StateT s m a
using Managed a
m = m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance MonadManaged m => MonadManaged (State.Lazy.StateT s m) where
using :: Managed a -> StateT s m a
using Managed a
m = m a -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance (Monoid w, MonadManaged m) => MonadManaged (Writer.Strict.WriterT w m) where
using :: Managed a -> WriterT w m a
using Managed a
m = m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
instance (Monoid w, MonadManaged m) => MonadManaged (Writer.Lazy.WriterT w m) where
using :: Managed a -> WriterT w m a
using Managed a
m = m a -> WriterT w m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using Managed a
m)
managed :: MonadManaged m => (forall r . (a -> IO r) -> IO r) -> m a
managed :: (forall r. (a -> IO r) -> IO r) -> m a
managed forall r. (a -> IO r) -> IO r
f = Managed a -> m a
forall (m :: * -> *) a. MonadManaged m => Managed a -> m a
using ((forall r. (a -> IO r) -> IO r) -> Managed a
forall a. (forall r. (a -> IO r) -> IO r) -> Managed a
Managed forall r. (a -> IO r) -> IO r
f)
managed_ :: MonadManaged m => (forall r. IO r -> IO r) -> m ()
managed_ :: (forall r. IO r -> IO r) -> m ()
managed_ forall r. IO r -> IO r
f = (forall r. (() -> IO r) -> IO r) -> m ()
forall (m :: * -> *) a.
MonadManaged m =>
(forall r. (a -> IO r) -> IO r) -> m a
managed ((forall r. (() -> IO r) -> IO r) -> m ())
-> (forall r. (() -> IO r) -> IO r) -> m ()
forall a b. (a -> b) -> a -> b
$ \() -> IO r
g -> IO r -> IO r
forall r. IO r -> IO r
f (IO r -> IO r) -> IO r -> IO r
forall a b. (a -> b) -> a -> b
$ () -> IO r
g ()
with :: Managed a -> (a -> IO r) -> IO r
with :: Managed a -> (a -> IO r) -> IO r
with Managed a
m = Managed a -> forall r. (a -> IO r) -> IO r
forall a. Managed a -> forall r. (a -> IO r) -> IO r
(>>-) Managed a
m
runManaged :: Managed () -> IO ()
runManaged :: Managed () -> IO ()
runManaged Managed ()
m = Managed ()
m Managed () -> (() -> IO ()) -> IO ()
forall a. Managed a -> forall r. (a -> IO r) -> IO r
>>- () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return