{- | Module : Network.Monad.Class Copyright : (c) Henning Thielemann, 2009 License : BSD Maintainer : http@henning-thielemann.de Stability : experimental Portability : non-portable (not tested) With this monad we abstract from the IO monad, which also allows us to process data lazily or offline. -} {- How to use ByteString: http://nominolo.blogspot.com/2007/05/networkhttp-bytestrings.html -} module Network.Monad.Transfer where import qualified Network.Stream as Stream import Control.Monad.IO.Class (MonadIO(liftIO), ) import qualified Control.Monad.Exception.Asynchronous as Async import qualified Control.Monad.Exception.Synchronous as Sync import Control.Applicative (WrappedMonad(WrapMonad), unwrapMonad, ) import Data.Monoid (Monoid, ) type SyncExceptional m = Sync.ExceptionalT Stream.ConnError m type AsyncExceptional m = Async.ExceptionalT Stream.ConnError m data T m body = Cons { readLine :: AsyncExceptional m body, readBlock :: Int -> AsyncExceptional m body, writeBlock :: body -> SyncExceptional m () } liftSync :: Monad m => m (Stream.Result a) -> SyncExceptional m a liftSync = Sync.fromEitherT liftAsync :: (Monad m, Monoid a) => m (Stream.Result a) -> AsyncExceptional m a liftAsync = Async.mapExceptionalT unwrapMonad . Async.fromSynchronousMonoidT . Sync.mapExceptionalT WrapMonad . liftSync liftIOSync :: MonadIO io => IO (Stream.Result a) -> SyncExceptional io a liftIOSync = liftSync . liftIO liftIOAsync :: (MonadIO io, Monoid a) => IO (Stream.Result a) -> AsyncExceptional io a liftIOAsync = liftAsync . liftIO {- liftIOAsync = Async.ExceptionalT . liftM (Async.fromSynchronous mempty) . Sync.runExceptionalT . liftIOSync -} -- Async.fromSynchronousMonoidT . liftIOSync