Иногда мне нужно использовать несколько вложенных MonadTrans
. Например, я бы поставил MaybeT
внутренности ExceptT
, чтобы подражать continue
и break
в императивном программировании:Есть ли лучший способ, чем писать `lift` перед каждым `IO` в вложенном` MonadTrans`?
runExceptT . forM [1..] $ \ _ -> runMaybeT $ do
...
mzero -- this mimics continue
lift $ throwE "..." -- this mimics break
lift . lift $ putStrLn "Hello!"
...
Однако, как выше показывает код, каждый раз, когда мне нужно сделать любое IO
внутри этого «искусственный петля ", мне нужно поставить уродливый lift . lift
перед этим. Представьте себе, если у меня есть еще более сложные гнездования и много операций IO
, это быстро становится анонимным. Как сделать код более чистым и более кратким?
Работает ли 'liftIO'? – ErikR
Обратите внимание, что в некоторых случаях более эффективно поднимать вещи в блоках. 'lift $ do {x; y; z}' должно быть предпочтительнее: 'do {lift x; подъем y; подъем z} '. Если это окажется проблемой в узком цикле, вам может понадобиться 'lift $ do {blah; лифт. – dfeuer
Возможный дубликат [стека штанов Flatten] (http://stackoverflow.com/questions/32551152/flatten-monad-stack) – jakubdaniel