Lift a function to a Conduit Sink
Question
I have a function f :: ByteString -> String
, and need a Sink ByteString (ResourceT IO)
.
How do I get this?
Unfortunately, the docs were not very helpful...
Solution
I'm not sure why you need anything to do with resourceT in this conduit.
In order to return it all in one big string composed from all the little bytestrings, you'll have to accumulate pieces for awhile, then return it a the end.
fSink :: Monad m => Sink ByteString m String
fSink = go []
where
go accum = do
x <- await
case x of
Nothing -> return . f . B.concat . reverse $ accum
Just x' -> go (x':accum)
OTHER TIPS
Here's a general solution to the problem: let's take any function i -> r
, where i
is a Monoid
, and turn it into a sink by folding all of the await
s up with mappend
.
import Data.Conduit
import Data.Conduit.List as CL
import Data.Monoid
monoidFold :: (Monoid i, Monad m) => (i -> r) -> Sink i m r
monoidFold f = f `fmap` CL.fold mappend mempty
Since ByteString
is a Monoid
, your function of type ByteString -> String
can be used as the argument of monoidFold
.
myMD5 :: ByteString -> String
monoidFold myMD5 :: Monad m => Sink ByteString m String
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow