In naive implementation, IMAP requires same constructor names in different context. For example, RECENT is used at the SEARCH command, STATUS command, and in STATUS response. In this case, I would like to define as follows...
type Mailbox = String data IMAPCommand = STATUS Mailbox [StatusQuery] | SEARCH [SearchQuery] : data StatusQuery = RECENT | MESSAGES | : data SearchQuery = RECENT | SEEN | : data MailboxData = RECENT Integer | SEEN Integer | :
In addition to this, IMAP commands are separated as some groups. For example, UID command is used for SEARCH, FETCH, STORE, and COPY. How can I describe this relation in the type definition?
By using polymorphic variant of OCaml, these can be described easily and elegantly.
In conclusion, such relations may be described using not only type definitions, but also function definitions.
IMAP, Internet Message Access Protocol, is a fairly complecated protocol (comparing with POP3). Its specification can be read as RFC 3501.
I worry about the typing of IMAP commands. In normal protocol, the type of a client command can be written such as `Connection -> Request -> IO Response'. However, IMAP server may also return a status update data.
The server program can notify its clients with a status update untagged data. Assume that there is a client connecting to a server and the server may receive a new mail during the connection, for example. In normal, such newly received mail cannot be read from the client because the connection is established before the reception of the mail. However, the server may notify the client as that `it has a new mail'. Any commands may have such status update data.
Therefore, the type of a IMAP command should be `Connection -> Request -> IO (Response, Maybe StatusUpate)', but such typing will be annoying in many case...
Certainly, such typing can be hidden with StateT or WriterT. But is it clever approach?
BTW, I test the behavior of IMAP with Courier-IMAP, an implementation of IMAP, but it will not send any status update data with a command except NOOP. mmm....
At first, my plan is as follows.
First, I'll collect up some libraries which relates with network. For example, HTTP, MissingH (FTP), HAppS (DNS, HTTP, SMTP), and WASH-MAIL (MIME) are the candidates. Second, I'll implement other lacking protocols such as IMAP. POP3 and SMTP is aready implemented by me (see hazakura project).
And third, I'll fix up the libraries -- API level consistency is important for the programmer. The similar naming and similar API is required.
Finally, I'll set up a kind of test suit. Because the validation for the network behavior is hard to describe, the test will be a text level (local) check of query string, or parser for the peer response.
By now, the status is `collect up'. There are some problems to importing other libraries -- but, the most difficult problem is not coding. It is license problem (sigh).
I also read RFC 3501 and start to implement Network.IMAP.
HaskellNet is a library for network protocols such as SMTP, POP3, IMAP, HTTP, FTP and so on. In this blog, I will write my thought about HaskellNet design and implementation and report the progress of my project.
I write it in advance: I have no confidence for my English skill, so I will make trivial (grammatical) mistakes. In fact, this blog is also for my English training. If you find some mistakes or unnatural phrases, feel free to point them out.
If not, any comments are welcome.