Open ppetr opened 11 years ago
This is something that I would love to see implemented. It would do wonders for a project that I was participating on that was more or less abandoned a while ago because of difficulties with this and related issues.
I'd also be willing to participate if I can be of any help.
Great! I don't have a strong preference as to which approach is taken. I also don't have time to work on this myself right now, so I'm going to be especially appreciative of anyone who wants to take this on. :) With that said, the MonadIO
approach seems like a good middle ground for now until something clearer with e.g. conduit
arises. As far as I can tell, there is not a community consensus on which iterative I/O approach to use, anyway. Regardless: if you want to hack up a conduit
implementation just to see how it might go, that would be great. Or you can just submit a pull request for the MonadIO
approach and have done with it.
@jtdaugherty It seems that converting to MonadIO
is just enough so that it's possible to support conduit. I hacked a function that converts a conduit into a MonadIO
variant of BSStream
:
conduitToStream
:: (MonadIO m)
=> Source m ByteString
-> Sink (Flush ByteString) m ()
-> m (BSStreamM m)
Similarly, I constructed
tlsContextConduit
:: (MonadIO m)
=> Context
-> (Source m ByteString, Sink (Flush ByteString) m ())
for TLS contexts from Network.TLS
. Combined together, I got IMAP working on TLS.
One problem is that it doesn't really make sense to close a conduit. Another conduit can be appended after it and continue its processing. This can be also viewed as that closing a connection is the responsibility of whoever created it, not IMAP's. So currently for conduits bsClose
does nothing and bsIsOpen
return always True
. Any ideas?
With this structure, I think we could
MonadIO
everywhere.conduit
and provide BSStream
s from conduits.I think having a separate integration package like HaskellNet-conduit
makes a lot of sense. As for the specifics of how best to go about doing it, I really couldn't say. :)
I wanted to use IMAP with TLS and this turned out to be quite complex. (Relates to #7.) So far, I found these solutions:
Use
MonadIO
instead ofIO
everywhere. I already tried this variant in this branch for IMAP. It seems to work well and I was able to fuse such patched IMAP with network-conduit. The main part looks like this:Here
BSStreamM
is a (backward compatible) modification that takes an arbitraryMonadIO
instead ofIO
. This allows us to run the whole code inConduit
instead ofIO
and so the actions inBSStreamM
can be operations constructed usingConduit
primitives. (Full example code here).This modification adds generality and the only loss is slightly more complex type signatures.
IO
. I don't have a clear picture yet. The general idea is that connection wouldn't hold aBSStream
but aSink
for network output and aResumableSource
for network input. This would allow to plug in any conduit, even a pure one (for testing, for example).I'm willing to participate on those changes, if we reach some consensus.