避免在 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 操作,这是无法避免的。
是的,当然。 Process
是 MonadIO
的实例,因此您可以
let run = liftIO . runApp
相反。
我正在使用 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 操作,这是无法避免的。
是的,当然。 Process
是 MonadIO
的实例,因此您可以
let run = liftIO . runApp
相反。