Search code examples
haskellhaskell-pipeslifting

Pipes.Safe - how to use mapM


I have the following code with a pipe which is ok without the second pipe (>-> P.mapM ( fillMD5)). fillMD5 is an operation a -> IO a.

runSafeT $ runEffect $
     every (senseRecursive5  startfpo)
        >-> P.mapM ( fillMD5)
        >-> P.map fp2rdf  
        >-> toNTriple houtfile   

The error is :

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

I understand that the type of mapM is

mapM :: Monad m => (a -> m b) -> Pipe a b m r

but I do not see how to lift this into Safe.SafeT?


Solution

  • SafeT is a monad transformer, and so SafeT IO is a composite monad with IO wrapped in SafeT. To use fillMD5, you need to lift the computation it produces to the composite monad using lift (from the MonadTrans class):

        >-> P.mapM (lift . fillMD5)
    

    As fillMD5 produces an IO action, you can also use liftIO, which comes from the MonadIO instance of SafeT:

        >-> P.mapM (liftIO . fillMD5)