避免在 Process Monad 中使用 `unsafePerformIO` 进行交互

Avoid `unsafePerformIO` for interaction in a Process Monad

我正在使用 Cloud Haskell 进行消息处理。我还使用一个通用的 monad 转换器堆栈(底部有 IO)来跟踪状态、配置等。

我 运行 遇到了必须使用 unsafePerformIO 在 Process monad 中工作的情况。我正在描述下面的情况。请记住这是一个非常人为的例子来简化和展示问题的关键

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

unsafePerformIO 可以通过某种方式避免吗?我知道 Process monad 本身只是 IO monad 的包装器,但在我的转换器堆栈中有一些必不可少的 IO 操作,这是无法避免的。

是的,当然。 ProcessMonadIO 的实例,因此您可以

let run = liftIO . runApp

相反。