MonadResource用于读取具有错误处理的文件

时间:2017-10-28 12:47:05

标签: haskell monads monad-transformers conduit

我正在创建一个读取二进制文件的Conduit。东西可能出错了,所以我需要一个有错误处理的monad;现在Maybe已经足够了。

我想使用sourceFile,这要求管道monad为MonadResource,这就是问题的症结所在。

我从the docs看到,例如MaybeT m有一个实例,但它需要m已经是MonadResource;事实上,所有情况都是如此。由于我的理解有限,这听起来像鸡蛋和鸡蛋的东西,要求我用手写一个MonadResource实例,无论如何?

我认为要读取文件,我的monad必须包含IO。那么这一切是否意味着我必须为MonadResource编写MaybeT IO个实例?如果是这样,关于如何做到的任何指针?

1 个答案:

答案 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!