2016-03-23 23 views
1

Bir dizini yinelemeli olarak çaprazlamak ve dosyaları yazdırmak için haskell-pipe kullanıyorum. Monad transformatörü olan Producer'ın istisnalarını nasıl ele alabilirim? Bu durumda bracket ve handle çalışmaz.Monad transformatörlerinde istisnaları yakalamak

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" 

cevap

3

Sen Pipes.Safe dan bracket, handle ve diğer istisna işleme tesisleri alabilirsiniz.

+0

Teşekkürler! Boru tesisatının sonuç bölümünde borulara güvenli bir şekilde değindim. Oldukça gizli. –