[Haskell-cafe] some question about conduit usage

Michael Snoyman michael at snoyman.com
Sat Feb 11 20:02:17 CET 2012


On Fri, Feb 10, 2012 at 4:26 PM, Alexander V Vershilov
<alexander.vershilov at gmail.com> wrote:
> Hello, cafe!
>
> I have somq questions about proper conduit usage in some usecases,
> I can't find a good way to solve this problems
>
> 1). adding additional source to conduit processing [1]
> Sometimes I want to run a Source and send use it to produce output
> e.g.
> have something like:
>
>> runSource :: ResourceT m => a -> Source m b
>> runSource = undefined
>>
>> test1 :: ResourceT m => Conduit a m b
>> test1 = Conduit push close
>>   where
>>     push = runSource
>>     close = undefined
>> -- In my first problem I've got
>> -- push i = case i of Left _ -> oneValue ; Right -> runSource
>> -- but it can be solved with oneValue = sourceList [oneValue]

We have a `sequenceSink` function that takes a `Sink` and turns it
into a `Conduit` by running it repeatedly. It looks to me like the
best approach would be to have an equivalent `sequenceSource`,
something like:

    sequenceSource :: (a -> Source m b) -> Conduit a m b

I can help out with implementation.

> 2). pushing data back [1]
>
> e.g. I have
>> test2 :: ResourceT Conduit ByteString m b
>> test2 = Conduit push close
>>   where
>>     conduit i = let (item,lft) = parse i
>>                 in -- I want to send lft back to test2 and
>>                    -- process item
>> -- in the other case I want to be able to send data back to
>> -- previous or arbitrary level, e.g.
>> test1 $= test2 $= test3
>>           ^--------| (<<<=) lft

This is purposely not allowed currently, for various low-level
reasons. I can get into details if anyone's curious, but don't have
time at the moment.

> 3). split stream to send it to different Sinks, e.g.
>> sendToAll test3 [sink1,sink2,sink3]

It's mostly straight-forward to implement, but there are some
questions. In particular: what do you do if sink1 terminates earlier
than sink2? Do you call sinkClose on sink2, or continue pulling data
until all of the sinks close? Also, I think it could be a Sink, e.g.:

    sendToAll :: [Sink a m b] -> Sink a m [b]

> 4). send additional data from the other place, e.g.
>> src $= handle $$ snk
>> --  state -^
>> -- I want to send message into handle to change it's state
>> -- It can be done with stm-conduit and Either (Left for commands
>> -- and Right for data), but it seems its overkill

I'm not sure what you're looking for here. You want to control the
behavior of src from snk? If you just want to modify the handle from
snk, you could pass the handle to snk directly.

Michael



More information about the Haskell-Cafe mailing list