[Haskell-cafe] Re: Network.HTTP+ByteStrings Interface--Or: How to
shepherd handles and go with the flow at the same time?
Pete Kazmier
pete-expires-20070513 at kazmier.com
Fri May 25 23:51:01 EDT 2007
As a newbie to Haskell, I found your thorough analysis very
interesting. Thanks for the great read! I have a few questions
regarding some of your comments, see below:
Jules Bean <jules at jellybean.co.uk> writes:
> E,F. Progressive GET
> pSynGET :: URL -> ((Bool,ByteString) -> IO ()) -> IO ()
> pAsynGET :: URL -> ((Bool,ByteString) -> IO ()) -> IO (MVar ())
>
> (This is a particular simple case of Oleg's iteratees, I
> think) Download the data at whatever speed is convenient. As data
> arrives, feed it to the 'callback' provided. The ByteString is the
> new chunk of data, the 'Bool' is just supposed to indicate whether
> or not this is the final chunk.
> Incidentally there are more complex options than (Bool,Bytestring)
> -> IO (). A simple and obvious change is to add a return
> value. Another is a 'state monad by hand', as in (Bool,Bytestring)
> -> s -> s, and change the final return value of the type to IO s,
> which allows the callback to accumulate summary information and
> still be written as pure code.
I want to be sure that I understand the implications of the callback
function returning an IO action as originally proposed versus it being
a pure function. It would seem to me that if it were a pure callback
the usefulness would be limited as I would not be able to take the
data read from the network and immediately write it out to a file. Is
this correct?
And if the above is correct, is there a way to define the callback
such that one does not have to hardcode the IO monad in the return
type so you can have the best of both worlds?
> Other options allow the 'callback' to request early termination,
> by layering in an 'Either' type in there.
I believe the ability to request early termination is important, and
was one of the nice features of Oleg's left-fold enumerators. It
would be a shame if the API did not offer this capability.
> Another more sophisticated option, I think, is the higher rank
>
> MonadTrans t => URL ->
> ((forall m. Monad m) => (Bool,ByteString) -> t m)
> -> t IO ()
>
> ...which, unless I've made a mistake, allows you to write in 'any
> monad which can be expressed as a transformer', by transforming it
> over IO, but still contains the implicit promise that the
> 'callback' does no IO. For example t = StateT reduces to the
> earlier s -> s example, in effect, with a slightly different data
> layout.
I don't fully understand this, but would this prevent one from calling
IO actions as it was receiving the chunks in the callback (such as
writing it to a file immediately)?
More information about the Haskell-Cafe
mailing list