Avoid `unsafePerformIO` for interaction in a Process Monad

79 Views Asked by At

I am using Cloud Haskell for message processing. I am also using a general monad transformer stack (with IO at the bottom) for some general tracking of state, configuration etc.

I am running into a situation where I have to use unsafePerformIO for working inside the Process monad. I am describing the situation below. Please bear in mind this is a much contrived example to simplify and present the crux of the problem

data AppConfig
data AppState 

type App = ReaderT AppConfig (StateT AppState IO)

runApp :: App a -> Int -> IO (a, AppState)
runApp k maxDepth =
    let config = AppConfig maxDepth
        state = AppState 0
    in runStateT (runReaderT k config) state

msgHandler :: App ()
msgHandler = -- some message handling logic here --

runServer :: Process ()
runServer = do
  let run handler = return $ unsafePerformIO $ runApp handler
  (_,_) <- receiveWait [match $ run taskSubmissionHandler]
  runServer

Can this unsafePerformIO be somehow avoided? I understand that the Process monad itself is just a wrapper around the IO monad but there are certain IO operations which are essential inside my transformer stack, which cannot be avoided.

1

There are 1 best solutions below

0
On BEST ANSWER

Yes, sure. Process is an instance of MonadIO, so you can just

let run = liftIO . runApp

instead.