How do I create a monad that allows IO but is not MonadIO?

I am trying to create a monad where only certain I / O functions are allowed. This means that this hypothetical monad cannot MonadIO

and cannot cause liftIO

.

Here is what I have so far, but I am stuck with an instance Monad

for AppM

:

data AppM a = AppM {unwrapAppM :: ReaderT Env (LoggingT IO) a}

instance Functor AppM where
  fmap fn appm = AppM $ fmap fn (unwrapAppM appm)


instance Applicative AppM where
  pure a = AppM $ pure a

      

+3


source to share


1 answer


If you just want to hide the MonadIO

-ness of yourAppM

I would go on and put

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

      

and change your ad data

to

newtype App a = App {runApp :: ReaderT Env (LoggingT IO) a}
              deriving (Functor, Applicative, Monad, MonadReader Env,
                       , MonadLoggerIO }

      

So yours App

doesn't matter MonadIO

if you need liftIO

both actions that you can provide to those inside your library, for example

putStrLn :: String -> App ()
putStrLn = fmap App . liftIO Prelude.putStrLn

      

Note: liftIO

intended for ReaderT Env (LoggingT IO) ()

, which is then wrapped in App

, and you do not disclose full I / O capabilities.

Update



On the question of how to implement Functor

, Applicative

and Monad

it's just a problem of the wrapping / unpacking:

instance Functor App where
   fmap f = App . fmap f . runApp

instance Applicative App where
  pure = App . pure
  mf <*> mx = App (runApp mf <*> runApp mx)

instance Monad App where
  mx >>= f = App $ (runApp mx) >>= (runApp . f)

      

the last line is the only tricky one - like

>>= :: ReaderT Env (LoggingT IO) a -> (a -> ReaderT Env (LoggingT IO) b) -> ReaderT Env (LoggingT IO) b

      

but mx :: App a

also f :: a -> App b

, therefore we need

runApp :: App a -> ReaderT Env (LoggingT IO) a

      

to expand the result type f

to work in an expanded setup, which seems really obvious when writing, but can cause headaches before then.

Update2

I found that someone linked me for a long time (but in the same galaxy) from monad reader Ed Z. Yang - Three Monads (logic, hint, glitch)

+9


source







All Articles