用于读取带有错误处理的文件的 MonadResource
MonadResource for reading files with error handling
我正在创建一个将读取二进制文件的管道。事情可能会出错,所以我需要一个带有错误处理的 monad;现在 Maybe
已经足够了。
我想使用 sourceFile
,这要求管道 monad 是 MonadResource
,这就是问题的关键。
我从 the docs 看到,例如MaybeT m
有一个实例,但它要求 m
已经是一个 MonadResource
;事实上,所有情况都是如此。以我有限的理解,这听起来有点像先有鸡还是先有蛋的问题,无论如何都需要我手写一个 MonadResource
实例?
我假设要读取文件,我的 monad 必须包含 IO。那么这一切是否意味着我必须为 MaybeT IO
编写一个 MonadResource
实例?如果是这样,关于如何做到这一点的任何指示?
一个简单的方法是使用tryC
例如:
module Main (main) where
import Conduit
import Control.Exception (SomeException)
import qualified Control.Monad.Trans.Resource as R
import Data.Monoid ((<>))
import System.Environment (getArgs)
main :: IO ()
main = do
[fname] <- getArgs
r <- R.runResourceT . runConduit . tryC $ sourceFile fname .| await >>= pure
case r of
Left e -> putStrLn $ "Failed to read file content with " <> show (e :: SomeException)
Right r' -> putStrLn $ "File content: " <> show r'
然后你得到:
[nix-shell:/tmp]$ ghc -Wall M.hs && ./M /tmp/doesnt_exist
[1 of 1] Compiling Main ( M.hs, M.o )
Linking M ...
Failed to read file content with /tmp/doesnt_exist: openBinaryFile: does not exist (No such file or directory)
[nix-shell:/tmp]$ ghc -Wall M.hs && ./M /tmp/hello-file
File content: Just "Hello world!
我正在创建一个将读取二进制文件的管道。事情可能会出错,所以我需要一个带有错误处理的 monad;现在 Maybe
已经足够了。
我想使用 sourceFile
,这要求管道 monad 是 MonadResource
,这就是问题的关键。
我从 the docs 看到,例如MaybeT m
有一个实例,但它要求 m
已经是一个 MonadResource
;事实上,所有情况都是如此。以我有限的理解,这听起来有点像先有鸡还是先有蛋的问题,无论如何都需要我手写一个 MonadResource
实例?
我假设要读取文件,我的 monad 必须包含 IO。那么这一切是否意味着我必须为 MaybeT IO
编写一个 MonadResource
实例?如果是这样,关于如何做到这一点的任何指示?
一个简单的方法是使用tryC
例如:
module Main (main) where
import Conduit
import Control.Exception (SomeException)
import qualified Control.Monad.Trans.Resource as R
import Data.Monoid ((<>))
import System.Environment (getArgs)
main :: IO ()
main = do
[fname] <- getArgs
r <- R.runResourceT . runConduit . tryC $ sourceFile fname .| await >>= pure
case r of
Left e -> putStrLn $ "Failed to read file content with " <> show (e :: SomeException)
Right r' -> putStrLn $ "File content: " <> show r'
然后你得到:
[nix-shell:/tmp]$ ghc -Wall M.hs && ./M /tmp/doesnt_exist
[1 of 1] Compiling Main ( M.hs, M.o )
Linking M ...
Failed to read file content with /tmp/doesnt_exist: openBinaryFile: does not exist (No such file or directory)
[nix-shell:/tmp]$ ghc -Wall M.hs && ./M /tmp/hello-file
File content: Just "Hello world!