1

我正在使用 haskell-pipes 递归遍历目录并打印文件。如何处理来自 Producer 的异常,它是一个 monad 转换器?bracket在这种情况下handle不工作。

import Control.Exception (handle, SomeException(..))
import Control.Monad (unless)
import System.FilePath.Posix ((</>))
import Pipes
import qualified Pipes.Prelude as P
import System.Posix.Directory (DirStream, openDirStream, closeDirStream, readDirStream)
import System.Posix.Files (getFileStatus, isDirectory)

produceFiles :: DirStream -> Producer FilePath IO ()
produceFiles ds = do
  path <- lift $ readDirStream ds
  yield path
  unless (path == "") $ produceFiles ds

getDC :: FilePath -> Producer FilePath IO ()
getDC top = do
  {-
    lift $ handle (\(SomeException e) -> putStrLn (show e)) $ do
    ds <- openDirStream top
    -- DOESN'T WORK: produceFiles ds
    -- I would have to "delift" the above somehow.
    closeDirStream ds
  -}
  ds <- lift $ openDirStream top
  produceFiles ds
  lift $ closeDirStream ds

getDC' :: FilePath -> Producer FilePath IO ()
getDC' top = getDC top >-> P.filter (`notElem` [".", ".."]) >-> P.map (top</>)

getDCR :: FilePath -> Producer FilePath IO ()
getDCR top = for (getDC' top) $ \f -> do
  st <- lift $ getFileStatus f
  if isDirectory st && f /= top
  then getDCR f
  else yield f

test top = runEffect $ for (getDCR top) (lift . putStrLn)

main = test "/usr/share"
4

1 回答 1

3

您可以从中导入brackethandle其他异常处理设施Pipes.Safe

于 2016-03-23T10:40:44.997 回答