Я использую библиотеку MongoDB для обработки данных из Mongodb. Существует Монада, называемая Action
, представляющая операцию чтения или записи БД https://github.com/TonyGen/mongoDB-haskell/blob/master/doc/tutorial.md
. Но, я нахожу, что когда я в Monad Action, я также хочу сделать некоторые IO, которые должны быть в IO Monad. Некоторые коды, такие какКак использовать IO Monad в другой Monad
-- `Action' is a Monad
--
intoFile :: String -> Cursor -> Action IO()
intoFile ric c = do
outH <- liftIO $ openFile ric AppendMode
liftIO $ hPutStrLn outH "Some log"
loopIntoFile outH c
liftIO $ hClose outH
Существует liftIO
перед любой IO
монады, и я думаю, что это может быть многословным. Любой краткий способ справиться с этим?
Там ISN «Это действительно хороший способ справиться с этим, поскольку действия« IO »реализованы исключительно как возвращающие« IO a »вместо« MonadIO m => ma'. Я часто вижу такие вещи, как 'where io = liftIO' для функций, а вместо' liftIO' используется функция 'io', чтобы уменьшить типизацию. В идеале мы имели бы 'hPutStrLn :: MonadIO m => Handle -> String -> m()', но мы не можем ожидать, что функции из 'base' будут зависеть от классов, определенных в сторонних библиотеках (даже если эти библиотеки часть платформы haskell). – bheklilr
Если у вас есть последовательность действий ввода-вывода, вы можете изменить 'do liftIO action1; liftIO action2' to 'liftIO $ do action1; action2', чтобы сэкономить некоторые лифты. – chi