The EC2 bindings are now in a github repo. It could do with a little code clean up–there’s a bit of unnecessary boilerplate here and there, and at some point I’d like to define some types so users don’t have to worry about mixing up volume ids with image ids and the like. But for now I’m focussing on getting it to properly deal with errors.

So far it can make calls to the EC2 API and parse them. Most of the API actions necessary for spinning up a VM are implemented (except for actually uploading a custom kernel to AWS — a subject for another post, I think).

But now for my Technical Problem. I spent a good part of the weekend thinking about this and it’s time for you to be plagued too. (I kid!)

Basically the compiler and I are currently wrestling over types. It’s making inferences that I don’t think are justified! See, I have functions like these:

val verb : Cohttp.Code.meth -> api_action -> ~parsing_fn:(api_response -> 'a) -> 'a Lwt.t
val get : api_action -> ~parsing_fn:(api_response -> 'a) -> 'a Lwt.t
(* There's also a `post`. Looks a lot like `get` *)

val parse_del_vol_response : api_response -> bool
(* EC2 returns true if the volume was deleted *)
val parse_reg_img_response : api_response -> img_id
(* EC2 returns the id of the image that was registered *)

The compiler sees delete_volume pass to get the function parse_del_vol_response, which returns bool, and goes, oh, yes, of course, ~parsing_fn is actually api_response -> bool even when the .mli file says it’s api_response -> 'a. (This is the unjustified assumption! Actually, well, I guess it is justifiable–it’s just unncessary, isn’t it?)

Then the compiler gets to register_image which uses parse_reg_img_response to parse the API response and return the id of a newly registered image–not a bool. At which point I get chewed out :/

Error: This expression has type api_response -> img_id
       but an expression was expected of type api_response -> bool
       Type img_id is not compatible with type bool 

For the moment I’ve managed to resolve this by explicitly stating that the parsing_fn parameter must be api_response -> 'a. Which is unfortunate because now I have to write

let get api_action (fn: api_response -> 'a) = verb `GET api_action fn

instead of the more beautiful

let get = verb `GET

Admittedly it’s not the end of the world, but surely this error shouldn’t occur at all? I’m somewhat miffed.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s