【问题标题】:MonadResource for reading files with error handlingMonadResource 用于读取带有错误处理的文件
【发布时间】:2017-10-28 12:47:04
【问题描述】:

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

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

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

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

【问题讨论】:

  • (MonadThrow m, MonadBase IO m, MonadIO m, Applicative m) => MonadResource (ResourceT m) 不是递归的。
  • 啊哈,错过了。我猜是时候深入了解ResourceT 的工作原理了..
  • 只是某种形式的main = runResourceT . runConduit $ sourceFile … 应该可以工作。

标签: haskell monads monad-transformers conduit


【解决方案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!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多