{-# LANGUAGE LinearTypes #-}
{-# LANGUAGE NoImplicitPrelude #-}

module Control.Monad.IO.Class.Linear where

import qualified Control.Functor.Linear as Linear
import Prelude.Linear
import qualified System.IO as System
import qualified System.IO.Linear as Linear
import System.IO.Resource.Linear (RIO)
import qualified System.IO.Resource.Linear as RIO

-- | Like 'NonLinear.MonadIO' but allows to lift both linear
-- and non-linear 'IO' actions into a linear monad.
class (Linear.Monad m) => MonadIO m where
  liftIO :: Linear.IO a %1 -> m a
  liftSystemIO :: System.IO a -> m a
  liftSystemIO IO a
io = IO a %1 -> m a
forall a. IO a %1 -> m a
forall (m :: * -> *) a. MonadIO m => IO a %1 -> m a
liftIO (IO a %1 -> IO a
forall a. IO a %1 -> IO a
Linear.fromSystemIO IO a
io)
  liftSystemIOU :: System.IO a -> m (Ur a)
  liftSystemIOU IO a
io = IO (Ur a) %1 -> m (Ur a)
forall a. IO a %1 -> m a
forall (m :: * -> *) a. MonadIO m => IO a %1 -> m a
liftIO (IO a -> IO (Ur a)
forall a. IO a -> IO (Ur a)
Linear.fromSystemIOU IO a
io)

instance MonadIO Linear.IO where
  liftIO :: forall a. IO a %1 -> IO a
liftIO = IO a %1 -> IO a
forall a (q :: Multiplicity). a %q -> a
id

instance MonadIO RIO where
  liftIO :: forall a. IO a %1 -> RIO a
liftIO = IO a %1 -> RIO a
forall a. IO a %1 -> RIO a
RIO.fromIO

instance (MonadIO m) => MonadIO (Linear.StateT s m) where
  liftIO :: forall a. IO a %1 -> StateT s m a
liftIO = m a %1 -> StateT s m a
forall (m :: * -> *) a. Monad m => m a %1 -> StateT s m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Linear.lift (m a %1 -> StateT s m a)
-> (IO a %1 -> m a) -> IO a %1 -> StateT s m a
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. IO a %1 -> m a
forall a. IO a %1 -> m a
forall (m :: * -> *) a. MonadIO m => IO a %1 -> m a
liftIO

instance (MonadIO m, Dupable r) => MonadIO (Linear.ReaderT r m) where
  liftIO :: forall a. IO a %1 -> ReaderT r m a
liftIO = m a %1 -> ReaderT r m a
forall (m :: * -> *) a. Monad m => m a %1 -> ReaderT r m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a %1 -> t m a
Linear.lift (m a %1 -> ReaderT r m a)
-> (IO a %1 -> m a) -> IO a %1 -> ReaderT r m a
forall b c a (q :: Multiplicity) (m :: Multiplicity)
       (n :: Multiplicity).
(b %1 -> c) %q -> (a %1 -> b) %m -> a %n -> c
. IO a %1 -> m a
forall a. IO a %1 -> m a
forall (m :: * -> *) a. MonadIO m => IO a %1 -> m a
liftIO