私は 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
while allFiles
hasMonadSafe m
とMonadIO 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 }
解釈方法がわからない 2 番目のエラーもあります。
編集: 他の型シグネチャは次のとおりです。
filterResults :: Config -> Result -> Result
filterNulls :: Result -> Bool
exportStream :: Config -> Producer Result IO () -> Effect IO ()