
I can only tell you what's useful for me as an API user. Since there are peculiar little differences between different kinds of sockets, my ideal would be every type of socket to have its own API functions, and then common patterns brought together with classes.
Ok, so the main alternatives are between - One API with a superset of the operations available on Handles. Some operations fail for some kinds of Handles. - A separate type and API for each kind of handle, defining only the operations available on that handle. Operations which several types of handle share are unified using classes. I agree the second option is conceptually cleaner, but I'm not sure I'm motivated enough to change given that the impact in terms of breaking existing code would be high. That's my opinion - perhaps others feel differently. There may be some useful middle ground that doesn't involve going the whole way, such as just separating streams and files.
Why isn't writeEnd the same as close?
On a TCP connection, one can still receive data after sending an end. My "close" is intended to be the last thing done with the connection as an object destructor: if called before sending and receiving end, it would simply forcibly close the connection.
At least the current API should have a way of doing this - it only has SocketPrim.shutdown which you can't use on a Handle.
Is there anything that is always a Source but not a Sink (or vice versa)?
Oh yes, lots of things. Standard input/output/error for instance. One might write code that did something like pipe from a Source to a Sink, and then one might want a Source constructed from a constant array. Or something. Stream-based encoding algorithms such as UTF-8 might make use of them:
encodeUTF8:: SourceChar -> SourceWord8
Yes, I can see that being able to plug together arbitrary sources and sinks could be useful. You don't have to separate sources and sinks to do this though - if Handle were a class, then you could define new instances for a constant array Handle, or an encoding layer on top of a raw Handle. Cheers, Simon

Simon Marlow
- A separate type and API for each kind of handle, defining only the operations available on that handle. Operations which several types of handle share are unified using classes.
This thread is revisiting discussion from the Haskell 1.3 IO library design - it might be useful to bring in some of the people involved in that (i.e., Kevin Hammond or Andy Gordin). The one bit of that that I do remember is that the Handle type was explicitly intended to cover a wide range of I/O devices not just files. After all, if it was only meant to do files, it'd be called "File" not "Handle". -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/

I really like the idea of a source and sink class, among other things it would allow things like a sink which spit out a cryptographic hash of everything that went through it discarding the data itself. or one which droped everything to an in-heap list. or even one that split the data into two and sent it to multiple sinks... such a framework would be very useful in real world programming. also, Haskell really really needs a standard 'Byte' type rather than confusing Char, but I have ranted about this before, I am glad to see other people think the same thing... :).. John -- --------------------------------------------------------------------------- John Meacham - California Institute of Technology, Alum. - john@repetae.net ---------------------------------------------------------------------------
participants (3)
-
Alastair David Reid
-
John Meacham
-
Simon Marlow