2016-03-23 8 views
1

私はhaskell-pipesを使用して、ディレクトリを再帰的に走査してファイルを出力しています。モナド変換器であるプロデューサから例外を処理するにはどうすればよいですか? brackethandleはこの場合動作しません。モナド変圧器の例外をキャッチ

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" 

答えて

3

あなたはPipes.Safeからbrackethandleおよびその他の例外処理施設をインポートすることができます。

+0

ありがとうございます!私は、パイプチュートリアルの結論のセクションでパイプセーフについて述べました。そこにはかなり隠されています... –