MonadResource用于读取具有错误处理的文件
问题描述:
我正在创建一个将读取二进制文件的Conduit。东西可能会出错,所以我需要一个monad来处理一些错误;现在Maybe
已经足够了。MonadResource用于读取具有错误处理的文件
我想使用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!
'(MonadThrow米,MonadBase IO米,MonadIO米,应用型米)=> MonadResource( ResourceT m)'不是递归的。 – melpomene
啊哈,错过了。时间潜入并学习'ResourceT'如何工作我猜.. – jorgen
只是某种形式的'main = runResourceT。 runConduit $ sourceFile ...应该可以工作。 –