Am Donnerstag, den 14.07.2011, 10:48 -0400 schrieb Markus Mottl: > 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.
Especially, polymorphic variants are not restricted to monomorphic types as exn is. For a complete example look here: https://godirepo.camlcity.org/svn/lib-pxp/trunk/src/pxp-engine/pxp_xpath.ml. It's an attempt to define xpath as an open polymorphic variant. The type open_expr is the open version of the xpath terms, expr is the closed. The corresponding evaluators are eval_open_expr and eval_expr. There is also a paper by Jacques Garrigue about this topic, but I cannot find it anymore in the web. Gerd > > Regards, > Markus > > On Thu, Jul 14, 2011 at 09:38, <[email protected]> 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 [email protected] > > -- ------------------------------------------------------------ Gerd Stolpmann, Bad Nauheimer Str.3, 64289 Darmstadt,Germany [email protected] http://www.gerd-stolpmann.de Phone: +49-6151-153855 Fax: +49-6151-997714 ------------------------------------------------------------ -- 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
