[Haskell-beginners] ODP: howto Pipe

PICCA Frederic-Emmanuel frederic-emmanuel.picca at synchrotron-soleil.fr
Mon Feb 22 08:39:17 UTC 2016

> First of all, (StateT Diffractometer (Pipe Engine Geometry IO) ())
> isn't the same as (Pipe Engine Geometry (StateT Diffractometer IO)
> ()), although I'm not sure what exactly the difference will be, as
> I've never used it the former way. This might be again a question for
> the Pipes mailing list.

ok, I will investigate this part :)

> Secondly:
> > but now if I remove the get and put lines, I get the segfault.
> Okay, I have no idea. As I see it, this shouldn't happen, as you're
> getting and putting the same pointer all the time. What if you remove
> the StateT altogether and just use the `dif` from the function
> argument, are you still getting segfaults? Also what about writting
> the function without using pipes, and using Pipes.mapM to make it a
> pipe like I mentioned? (if the only Pipes operation you're doing are
> an `await` in the beginning and a `yield` at the end, Pipes.mapM
> covers it)

Yes I get the segfault if I remove all the State Part and use directly the dif.

I think that I have something like this , I need to connect the life of one foreignPtr to another one.
This is why I put them all into the Diffractometer data.

But it seems that this is not the magic bullet in order to garanty the same life time for all of these foreignPtr.

I am wonderig if the fact that I use only one of the ForeignPtr in the solveTrajPipe function does not give a clu to haskell that he just need to keep a reference to the used one and get ride of the other one stored in dif.

withDiffractometer :: Diffractometer -> (Ptr HklEngineList -> IO b) -> IO b
withDiffractometer d fun = do
  let f_engines = difEngineList d
  withForeignPtr f_engines fun

then I extract a pointer from the engines one but as I am using the withForeingPtr I think that it is ok.

I would say that I am not yet a specialist of FFI and haskell, but I love this language a lot when I will manage this problem :))

solveTrajPipe' :: Diffractometer -> Pipe Engine Geometry IO ()
solveTrajPipe' dif = flip evalStateT dif $ forever $ do
    -- Inside here we are using `StateT Int (Consumer a IO) r`
    e <- lift await
    -- dif <- get
    let name = engineName e
    solutions <- lift . lift $ withDiffractometer dif $ \engines ->
     withCString name $ \cname -> do
       engine <- c_hkl_engine_list_engine_get_by_name engines cname nullPtr
       n <- c_hkl_engine_pseudo_axis_names_get engine >>= darrayStringLen
       solve' engine n e >>= getSolution0
    -- put dif
    lift $ yield solutions



Ps: just for fun I got this adding just a lift print :)

:~/hkl/contrib/haskell$ cabal run
Preprocessing executable 'ghkl' for hkl-
[3 of 5] Compiling Hkl.C            ( dist/build/ghkl/ghkl-tmp/Hkl/C.hs, dist/build/ghkl/ghkl-tmp/Hkl/C.p_o )

    Couldn't match kind `* -> *' with `*'
    Expected type: Diffractometer -> Proxy () Engine () Geometry IO ()
      Actual type: Diffractometer -> Proxy () Engine () Geometry IO ()
    Kind incompatibility when matching types:
      Diffractometer :: * -> *
      Diffractometer :: *
    The function `lift'ghc: panic! (the 'impossible' happened)
  (GHC version 7.6.3 for x86_64-unknown-linux):
        kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}

Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

More information about the Beginners mailing list