On Sunday, March 23, 2014 2:23:46 AM UTC+1, Gabriel Gonzalez wrote:
>
> 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.
>
This one doesn't work with lifted async since its signature still insists
on MonadBaseControl IO.
>
> 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 >-> ...
> ...
>
I'm using lifted async since some of my calls to runWorkers involve the
persistent library and without lifted async I get error messages like
Couldn't match type `IO'
with `SqlPersistT (NoLoggingT (ResourceT IO))'
Expected type: SqlPersistT (NoLoggingT (ResourceT IO)) ()
Actual type: IO ()
In the return type of a call of `runWorkers'
So I'll try plan B.
> 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] <javascript:>.
> To post to this group, send email to [email protected]<javascript:>
> .
>
>
>
--
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].