It depends your allocation pattern. If you only need to allocate a
single handle, then you can factor out the `withFile` outside of
`runWorkers` and pass the handle to `runWorkers`:
withFile "yourFile.txt" ReadMode $ \handle -> do
runWorkers handle ...
...
Then you use `fromHandle` within `runWorkers` to read from that handle.
If you need to allocate the handle within `runWorkers` for any reason,
then there are two alternatives.
A) First, `pipes-safe` doesn't support `MonadBaseControl` (because its
semantics are not well specified), so if you went that route you would
need to use the non-lifted `async` and do something like this:
...
inp <- async $ do
withFile someFile ReadMode $ \handle ->
runEffect $ fromHandle h >-> ...
...
B) Implement `withFile` in terms of `resourcet`, which does support
`MonadBaseControl`. In fact, I may replace `pipes-safe` with
`resourcet` since they are very similar to each other, with the main
difference being that I try to avoid `MonadBaseControl`. If you go this
route, then just use the `withFile` function from the following lpaste:
http://lpaste.net/101607
Then you can use that within your lifted `async` like this:
...
inp <- async $ do
withFile someFile ReadMode $ \producer ->
runEffect $ producer >-> ...
...
Let me know which solution works best for you. Right now I'm studying
whether or not to outsource `pipes-safe` to `resourcet` and your
feedback on this would be welcome.
On 03/18/2014 05:05 PM, Lieven Marchand wrote:
Hi,
I wrote a little routine to run a bunch of computations in parallel
using pipes like this
type Generator a b m = (Monad m) => a -> Producer b m ()
type Worker b c m = (Monad m) => Pipe b c m ()
type Sync c m = (Monad m) => Consumer c m ()
runWorkers n a g w s = do
(output, input) <- liftIO $ spawn Unbounded
(output', input') <- liftIO $ spawn Unbounded
inp <- async $ do
runEffect $ (g a) >-> toOutput output
liftIO performGC
out <- async $ do
runEffect $ fromInput input' >-> s
liftIO performGC
workers <- forM [1..n] $ \_ ->
async $ do
runEffect $ fromInput input >-> w >-> toOutput output'
liftIO performGC
mapM_ wait (inp:out:workers)
and now I want to use Pipes.Safe.Prelude's withFile in one of my
generators.
But when I tried to do
PSP.runSafeT $ runWorkers
I get the error
No instance for (MonadBaseControl IO (PS.SafeT IO))
arising from a use of `runWorkers'
Possible fix:
add an instance declaration for (MonadBaseControl IO (PS.SafeT IO))
and trying to fix this led me into a whole bunch of other problems.
What is the preferred way to do this kind of thing?
Thanks.
--
You received this message because you are subscribed to the Google
Groups "Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
--
You received this message because you are subscribed to the Google Groups "Haskell
Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].