Simple RabbitMQ client wrapper After reading this question, I've realized that I can do a lot to improve the quality of my question, so I've edited this question quite a bit.

I've been teaching myself F# in my spare time off and on for the last 6 months.  I've finally started getting comfortable enough with the language to feel that a lot of my code could be much better.  The problem is, I don't know what changes to make.

Here's what I'm interested in:


I'm using higher order functions to return functions for interacting with a specific message queue.  Is this a good design.  Would another F# developer feel comfortable with this?
Does this fit the idiomatic style of F#?
If you know RabbitMQ, are there any bugs which I may be creating here.


Here's the context of the little block of code:

I'm doing a lot of experiments with messaging systems and I've been using RabbitMQ as a messaging framework.  There's a .Net library for RabbitMQ but it's written in and for C#.  I can use it in F# but it feels clunky.  I wanted a small wrapper around the RabbitMQ library which which convert it into a more functional interface.  Also, this will hopefully make it very easy to use RabbitMQ in an F# program. 

My wrapper handles the following for RabbitMQ:


Connect to a RabbitMQ server
Create a function which will let you read one message from a queue
Create a function which will write a message to a queue
For both 2 and 3, if the queue doesn't exist, the queue will be created (that's the declareQueue)

module Client =
    let connectToRabbitMqServerAt address = 
        let factory = new ConnectionFactory(HostName = address)
        factory.CreateConnection()

    let openChannelOn (connection:IConnection) = connection.CreateModel()

    let private declareQueue (channel:IModel) queueName = 
        channel.QueueDeclare( queueName, false, false, false, null )

    let private publishToQueue (channel:IModel) queueName (message:string) =
        let body = Encoding.UTF8.GetBytes(message)
        channel.BasicPublish("", queueName, null, body)

    let createQueueReader channel queue = 
        declareQueue channel queue |&gt; ignore

        fun () -&gt; 
            let ea = channel.BasicGet(queue, true)
            if ea &lt;&gt; null then
                let body = ea.Body
                let message = Encoding.UTF8.GetString(body)
                Some message
            else
                None

    let createQueueWriter channel queue =
        declareQueue channel queue |&gt; ignore
        publishToQueue channel queue



An example use case would be:

// open a connection to a RabbitMQ broker
let connection = connectToRabbitMqServerAt "localhost"
let myChannel = openChannelOn connection

// Connect to a queue for writing
let writeToHelloQueue = createQueueWriter myChannel "hello"

// write the message "Hello, World" to the queue "hello"
"Hello, World" |&gt; writeToHelloQueue
Overall, this code looks very good.  Just two nitpicks here:


Give your function definitions lines to themselves:



let openChannelOn (connection:IConnection) = connection.CreateModel()




Use match statements unless you are checking a boolean value directly:





if ea &lt;&gt; null then
    let body = ea.Body
    let message = Encoding.UTF8.GetString(body)
    Some message
else
    None



Becomes:

match ea with
| null -&gt; None
| _ -&gt;
    let body = ea.Body
    let message = Encoding.UTF8.GetString(body)
    Some message