将Pipes.Safe与IO操作一起使用

时间:2015-11-05 21:51:52

标签: haskell haskell-pipes haskell-pipes-safe

我使用的是Pipes.Files,而后者又依赖于Pipes.Safe。我有这样的管道:

import Pipes
import Pipes.Files
import Pipes.Safe
import qualified Pipes.Prelude as P


allFiles :: (MonadIO m, MonadSafe m) => FilePath -> Producer FilePath m ()
allFiles path = find path (glob "*.hs" <> regular)

main :: IO ()
main = do
    args <- parseArgsOrExit patterns =<< getArgs  -- docopt stuff, not relevant
    let ins = args `getAllArgs` argument "paths"
    conf <- readConfig args
    forM_ ins $ \path -> do
        let source = allFiles path  -- here lies the problem
                  >-> P.mapM (liftIO . analyze conf)
                  >-> P.map (filterResults conf)
                  >-> P.filter filterNulls
        runSafeT $ runEffect $ exportStream conf source

问题是analyze的类型是

analyze :: Config -> FilePath -> IO Result

allFilesMonadSafe mMonadIO m限制。理论上liftIO应该注意这一点,但我得到了这个错误:

Main.hs:45:22:
    No instance for (Pipes.Safe.MonadSafe IO)
      arising from a use of ‘allFiles’
    In the first argument of ‘(>->)’, namely ‘allFiles path’
    In the first argument of ‘(>->)’, namely
      ‘allFiles path >-> P.mapM (liftIO . analyze conf)’
    In the first argument of ‘(>->)’, namely
      ‘allFiles path >-> P.mapM (liftIO . analyze conf)
       >-> P.map (filterResults conf)’

Main.hs:49:20:
    Couldn't match type ‘IO’ with ‘Pipes.Safe.SafeT IO’
    Expected type: Pipes.Safe.SafeT IO ()
      Actual type: IO ()
    In the second argument of ‘($)’, namely
      ‘runEffect $ exportStream conf source’
    In a stmt of a 'do' block:
      runSafeT $ runEffect $ exportStream conf source
    In the expression:
      do { let source
                 = allFiles path >-> P.mapM (liftIO . analyze conf)
                   >-> P.map (filterResults conf)
                   >-> P.filter filterNulls;
           runSafeT $ runEffect $ exportStream conf source }

还有第二个错误,我现在还不知道如何解释。

编辑:以下是其他类型的签名:

filterResults :: Config -> Result -> Result
filterNulls :: Result -> Bool
exportStream :: Config -> Producer Result IO () -> Effect IO ()

0 个答案:

没有答案