From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p6EEmre0030057 for ; Thu, 14 Jul 2011 16:48:53 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ap4EAI0AH05KfVM2kGdsb2JhbAA9AQMSEJgRNI52CBQBAQEBCQkNBxQEIa4XjCuCTYRMO4hqAgMGhjQEkmSJXIJePIMkUw X-IronPort-AV: E=Sophos;i="4.65,529,1304287200"; d="scan'208";a="113153198" Received: from mail-gw0-f54.google.com ([74.125.83.54]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 14 Jul 2011 16:48:48 +0200 Received: by gwb15 with SMTP id 15so195088gwb.27 for ; Thu, 14 Jul 2011 07:48:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=NfnEq5QbMwWDsp0qls7XOeKKtLKBcXHlKhEJ0anktLg=; b=eaCnA5gc9QBEcMPJwc1VmCBozuJbiP/oIndC1sjHu+0h4zwHa+jN4cLgTUTMtQOnSa N68t+GNlMhvY/ZVx0F06T+Js4AkzlxZpyxmC5ThlkB+pXKtJ2B0aiZNQ9J/q2SBvsgHP I0TFfmCoqZrMuF/WUD5U3zI6XQHGeQZJwGASk= MIME-Version: 1.0 Received: by 10.236.185.129 with SMTP id u1mr3168157yhm.380.1310654926813; Thu, 14 Jul 2011 07:48:46 -0700 (PDT) Received: by 10.236.203.193 with HTTP; Thu, 14 Jul 2011 07:48:46 -0700 (PDT) In-Reply-To: References: Date: Thu, 14 Jul 2011 10:48:46 -0400 Message-ID: From: Markus Mottl To: lpw25@cam.ac.uk Cc: caml-list@inria.fr Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p6EEmre0030057 Subject: Re: [Caml-list] Open datatypes Hi, it is possible to create open (i.e. extensible) datatypes with polymorphic variants, even allowing recursion. E.g.: type 't add_open = [ `Add of 't * 't ] type 't sub_open = [ `Sub of 't * 't ] let eval_add_open eval (`Add (l, r)) = eval l + eval r let eval_sub_open eval (`Sub (l, r)) = eval l - eval r "add_open" and "sub_open" are clearly completely independent from each other, both the datatypes and the evaluation functions. Now we combine these two datatypes and evaluation functions, still leaving the result extensible: type 't add_sub_open = [ 't add_open | 't sub_open ] let eval_add_sub_open eval = function | #add_open as t -> eval_add_open eval t | #sub_open as t -> eval_sub_open eval t Eventually you will want to "close" the extensible definitions for actual use. This basically just means tying the open ends: type add_sub = add_sub add_sub_open let rec eval_add_sub t = eval_add_sub_open eval_add_sub t In my experience using polymorphic variants for that purpose is hands down the most elegant way of achieving extensibility and composability. It is especially useful for creating domain-specific languages that can be quickly combined and extended. Regards, Markus On Thu, Jul 14, 2011 at 09:38, wrote: > > Hi all, > > I was wondering whether there was any particular reason why OCaml > doesn't allow the user to create open extensible datatypes like exn. > > I know that something similar can be created using local exceptions: > > module T = struct >  type t = exn > >  type 'a tvariant = (('a -> t), (t -> 'a option)) > >  let createVariant (type s) () = >    let module M = struct exception E of s end in >      (fun x -> M.E x), (function M.E x -> Some x | _ -> None) > >  let mkTVariant ((cnstr, _) :  'a tvariant) (x: 'a) = cnstr x > >  let matchTVariant ((_, destr) : 'a tvariant) (xt: t) = destr xt > end > > but it isn't very neat, and it seems that it would not be that difficult to > allow the user to declare types with the same properties as exn. > > Thanks, > > Leo > > -- > Caml-list mailing list.  Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs -- Markus Mottl        http://www.ocaml.info        markus.mottl@gmail.com