[Haskell-beginners] ODP: howto Pipe

Marcin Mrotek marcin.jan.mrotek at gmail.com
Fri Feb 19 08:05:31 UTC 2016

Well, if pipelining only the outermost layer is enough to improve
performance of your code, perhaps you could just move `yield` outside
all the `with...` functions, so everything stays in IO until it's
ready to yield the result:

solveTraj :: Factory -> Geometry -> Detector -> Sample -> Pipe Engine
Geometry IO ()
solveTraj f g d s = do
  e <- await
  let name = engineName e
  solution <- withSample s $ \sample ->
      withDetector d $ \detector ->
          withGeometry f g $ \geometry ->
              withEngineList f $ \engines ->
                withCString name $ \cname -> do
                  c_hkl_engine_list_init engines geometry detector sample
                  engine <- c_hkl_engine_list_engine_get_by_name
engines cname nullPtr
                  n <- c_hkl_engine_pseudo_axis_names_get engine >>=
                  return $ solve' engine n e >>= getSolution0
  yield solution

This can be further simplified to use the version of `mapM` from
Pipes.Prelude (https://hackage.haskell.org/package/pipes-4.1.8/docs/Pipes-Prelude.html)

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

This way your code would look more or less like it looked without
pipes, something like:

import qualified Pipes.Prelude as Pipes

runEffect $ for (each engines) >-> Pipes.mapM (solve' engine n e >>=
getSolution0) >-> P.print

Best regards,
Marcin Mrotek

More information about the Beginners mailing list