我正在创建一个读取二进制文件的Conduit。东西可能出错了,所以我需要一个有错误处理的monad;现在Maybe
已经足够了。
我想使用sourceFile
,这要求管道monad为MonadResource
,这就是问题的症结所在。
我从the docs看到,例如MaybeT m
有一个实例,但它需要m
已经是MonadResource
;事实上,所有情况都是如此。由于我的理解有限,这听起来像鸡蛋和鸡蛋的东西,要求我用手写一个MonadResource
实例,无论如何?
我认为要读取文件,我的monad必须包含IO。那么这一切是否意味着我必须为MonadResource
编写MaybeT IO
个实例?如果是这样,关于如何做到的任何指针?
答案 0 :(得分:1)
一种简单的方法是使用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!