3

I want calculating hash of http post body and parsing it simultaneously when receiving, so I need a function like this:

unionSinks :: Monad m => Consumer a m r1 -> Consumer a m r2 -> Consumer a m (r1, r2)
unionSinks = ...

sinkBody :: Monad m => FromJSON v => Consumer ByteString m (Digest SHA1, v)
sinkBody = sinkHash `unionSinks` sinkParser json

When I developed image uploading I used passthroughSink in similar way. But I don't needed the result of conduit, which saves image to file, in this case.

Generally, I know how to implement fork using MVar-like things, but I don't sure that this is optimal solution.

Kayo
  • 179
  • 8
  • I'm not sure I completely understand the question, but have you checked out 'ZipConduit' and more specifically 'ZipSink' (in Data.Conduit)? – creichert Aug 29 '15 at 15:23
  • I need the same input data for both consumers. Additionally I need values, which returned from both. – Kayo Aug 29 '15 at 16:20
  • Hmm, It seems this is what I need. I didn't carefully read the docs. Thanks. – Kayo Aug 29 '15 at 16:36

1 Answers1

4

Indeed you need ZipSink (or more general ZipConduit):

import Control.Applicative
import Data.Conduit

unionSinks :: (Monad m) => Sink a m r1 -> Sink a m r2 -> Sink a m (r1, r2)
unionSinks s1 s2 = getZipSink ((,) <$> ZipSink s1 <*> ZipSink s2)
Petr
  • 62,528
  • 13
  • 153
  • 317