caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Christopher L Conway" <cconway@cs.nyu.edu>
To: caml-list@yquem.inria.fr
Subject: wrapping parameterized types
Date: Thu, 3 May 2007 18:31:07 -0400	[thread overview]
Message-ID: <4a051d930705031531m396e42e7i6212137e2fb9cd53@mail.gmail.com> (raw)

I recently ran across a rather surprising behavior in the OCaml type
system. I hope somebody may be able to advise me how to work around it
(or at least explain to me why things are the way they are!).

Suppose I want to pass around a restricted, un-parameterized list type:

# type mylist = Intlist of int list | Strlist of string list ;;
type mylist = Intlist of int list | Strlist of string list

Now I end up doing a lot of tedious case splits, like:

# let length_of_mylist = function Intlist x -> List.length x | Strlist
x -> List.length x ;;
val length_of_mylist : mylist -> int = <fun>

What one would like is something like "app_to_mylist : ('a list -> 'b)
-> mylist -> 'b" so one could write "app_to_mylist List.length", but:

# let app_to_mylist f = function Intlist x -> f x | Strlist x -> f x ;;
Characters 65-66:
  let app_to_mylist f = function Intlist x -> f x | Strlist x -> f x ;;
                                                                   ^
This expression has type string list but is here used with type int list

The solution I've tripped over is to pass in separate functions for
the different cases, and then (only somewhat less tediously than
above) duplicate the same function at the call site:

# let app_to_mylist (fi,fs) = function Intlist x -> fi x | Strlist x -> fs x ;;
val app_to_mylist : (int list -> 'a) * (string list -> 'a) -> mylist -> 'a =
  <fun>
# let length_of_mylist = app_to_mylist (List.length, List.length);;
val length_of_mylist : mylist -> int = <fun>

I can't help but feel there is a more elegant way to handle this,
perhaps drawing in objects or functors. Any suggestions?

This question arises from an attempt to use the APRON library, which
provides types parameterized by numerical domain, alongside other
numerical tools in a uniform way---the APRON interface deals with the
parameterized types generically, but I need to hoist the abstraction
up one layer and deal with both APRON and non-APRON types generically.
The details are far too ugly to wade into here...

Thanks,
Chris


             reply	other threads:[~2007-05-03 22:31 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-05-03 22:31 Christopher L Conway [this message]
2007-05-03 23:16 ` [Caml-list] " Chris King
2007-05-04  1:10   ` skaller
2007-05-04  8:13     ` Dirk Thierbach
2007-05-04 11:47     ` rossberg
2007-05-04 12:13       ` Andrej Bauer
2007-05-04 13:34         ` Dirk Thierbach
2007-05-04 15:58           ` Christopher L Conway
2007-05-04  1:58   ` Christopher L Conway

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=4a051d930705031531m396e42e7i6212137e2fb9cd53@mail.gmail.com \
    --to=cconway@cs.nyu.edu \
    --cc=caml-list@yquem.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;
as well as URLs for NNTP newsgroup(s).