caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Polymorphic arguments
@ 2015-09-18 20:38 Martin Jambon
  0 siblings, 0 replies; only message in thread
From: Martin Jambon @ 2015-09-18 20:38 UTC (permalink / raw)
  To: caml-list

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-09-18 20:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-09-18 20:38 [Caml-list] Polymorphic arguments Martin Jambon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).