Tôi muốn bắt một ngoại lệ bên trong runResourceT mà không giải phóng các nguồn lực, nhưng chức năng bắt chạy tính toán bên trong IO. Có cách nào để bắt ngoại lệ bên trong runResourceT hoặc cách được đề xuất để cấu trúc lại mã?Làm thế nào để bắt một ngoại lệ bên trong runResourceT
Cảm ơn sự giúp đỡ của bạn.
{-# LANGUAGE FlexibleContexts #-}
module Main where
import Control.Exception as EX
import Control.Monad.IO.Class
import Control.Monad.Trans.Resource
type Resource = String
allocResource :: IO Resource
allocResource = let r = "Resource"
in putStrLn (r ++ " opened.") >> return r
closeResource :: Resource -> IO()
closeResource r = putStrLn $ r ++ " closed."
withResource :: (MonadIO m
, MonadBaseControl IO m
, MonadThrow m
, MonadUnsafeIO m
) => (Resource -> ResourceT m a) -> m a
withResource f = runResourceT $ do
(_, r) <- allocate allocResource closeResource
f r
useResource :: (MonadIO m
, MonadBaseControl IO m
, MonadThrow m
, MonadUnsafeIO m
) => Resource -> ResourceT m Int
useResource r = liftIO $ putStrLn ("Using " ++ r) >> return 1
main :: IO()
main = do
putStrLn "Start..."
withResource $ \r -> do
x <- useResource r
{-- This does not compile as the catch computation runs inside IO
y <- liftIO $ EX.catch (useResource r)
(\e -> do putStrLn $ show (e::SomeException)
return 0)
--}
return()
putStrLn "Done."
Cảm ơn bạn đã trả lời và bình luận của bạn. Nó hoạt động như mong đợi và giúp tôi hiểu rõ hơn về máy biến áp monads. – jedf