[Haskell-cafe] "mapping" an Enumerator
Kannan Goundan
kannan at cakoose.com
Wed Dec 21 13:14:22 CET 2011
Michael Snoyman wrote:
> On Wed, Dec 21, 2011 at 12:59 PM, Kannan Goundan <kannan at cakoose.com>
> wrote:
>> Michael Snoyman wrote:
>>
>>> On Wed, Dec 21, 2011 at 12:35 PM, Kannan Goundan <kannan at cakoose.com>
>>> wrote:
>>>> I'm using the Data.Enumerator library. I'm trying to write a "map"
>>>> function that converts an Enumerator of one type to another.
>>>> Something like:
>>>>
>>>> mapEnum :: Monad m =>
>>>> (a -> b) ->
>>>> Enumerator a m r ->
>>>> Enumerator b m r
>>>>
>>>> Any hints?
>>>>
>>>> (My exact use case is that I have a ByteString enumerator and I need
>>>> to pass it to something that requires a Blaze.Builder enumerator.)
>>>>
>>>>
>>>> _______________________________________________ Haskell-Cafe mailing
>>>> list
>>>> Haskell-Cafe at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>>>
>>> You can use the Data.Enumerator.List.map function to create an
>>> Enumeratee, and then the Data.Enumerator.$= operators to join them
>>> together. Something like:
>>>
>>> mapEnum f enum = enum $= EL.map f
>>
>> I tried something like that but the resulting type isn't quite what I'm
>> looking for.
>>
>> mapEnum :: Monad m =>
>> (a -> b) ->
>> Enumerator a m (Step b m r) ->
>> Enumerator a m r
>>
>> (BTW, Michael, my exact use case is that I have ByteString enumerators,
>> but your HTTP-Enumerator library wants Blaze.Builder enumerators :-)
>>
>>
>> _______________________________________________ Haskell-Cafe mailing
>> list
>> Haskell-Cafe at haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
> Huh, I'm stumped ;). John: is this possible in enumerator?
>
> In general though: do you need precisely that type signature? Most of
> the time, Enumerators have polymorphic return types. It might be a
> problem from http-enumerator requiring (), but I *think* we can work
> around that.
>
> Michael
You're right -- now that I think about it, I don't really care what the
type of 'r' is. (Boy, I could have saved several hours today if I had
realized that earlier :-)
But yeah, I'm having trouble matching the () in http-enumerator's
interface. (I wonder if it's because I'm trying to use a fully concrete
helper type 'MyRequestBody'):
data MyRequestBody = MyRequestBody Int64 (Enumerator ByteString IO ())
myHttp :: URL -> MyRequestBody -> IO ()
myHttp url (MyRequestBody len bsEnum) = ...
where
builderEnum = mapEnum BlazeBS.fromByteString bsEnum
reqBody = RequestBodyEnum len builderEnum
GHC tells me that mapEnum expects bsEnum to be:
Enumerator ByteString IO (Step Blaze.Builder IO ())
But it is actually:
Enumerator ByteString IO ()
Wonder if I can use a "forall" in the definition of MyRequestBody to fix
things without introducing an externally visible type parameter...
Also, thanks for your help so far!
More information about the Haskell-Cafe
mailing list