Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Martin Jambon <martin.jambon@ens-lyon.org>
To: caml-list@inria.fr
Subject: [Caml-list] Polymorphic arguments
Date: Fri, 18 Sep 2015 13:38:53 -0700	[thread overview]
Message-ID: <55FC765D.4020005@ens-lyon.org> (raw)

Is there a way to make this work?

   let get_a resource =
     123

   let get_b resource =
     "abc"

   let get_a_b with_resource =
     (with_resource get_a, with_resource get_b)
                                         ^^^^^
   Error: This expression has type 'a -> bytes
   but an expression was expected of type 'a -> int
   Type bytes is not compatible with type int

... such that the function get_a_b is simply called by passing a 
with_resource function as argument without exotic syntax or annotation 
required from the user, e.g.

   let with_resource f =
     ...

   let a, b = get_a_b with_resource

I know the solution with a polymorphic record, but it is cumbersome to 
use since the with_resource function has to be wrapped in a record. I am 
unclear on what is possible to do without a record.

The following works and I'd like to avoid that:

   type resource

   type with_resource = {
     with_resource: 'a. (resource -> 'a) -> 'a;
   }

   let get_a resource =
     123

   let get_b resource =
     "abc"

   let get_a_b {with_resource} =
     (with_resource get_a, with_resource get_b)

Note that in practice this is used with computations that take place at 
different times and one of the goals is to avoid hanging on to the 
resource for too long, so the following is not acceptable:

   let get_a_b with_resource =
     with_resource (fun resource ->
       get_a resource;
       sleep 60;
       get_b resource
     )

With lwt, a sample with_resource function would be the following 
with_connection:

   val with_connection : (connection -> 'a Lwt.t) -> 'a Lwt.t

   let with_connection f =
     get_connection () >>= fun conn ->
     Lwt.finalize f (fun () -> recycle_connection conn)

and the desired get_a_b function would be:

   let get_a conn : int Lwt.t = ...
   let get_b conn : string Lwt.t = ...

   let get_a_b with_connection =
     with_connection get_a >>= fun a ->
     Lwt_unix.sleep 60. >>= fun () ->
     with_connection get_b >>= fun b ->
     Lwt.return (a, b)

Martin

                 reply	other threads:[~2015-09-18 20:39 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55FC765D.4020005@ens-lyon.org \
    --to=martin.jambon@ens-lyon.org \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox