Hi,

Polymorphic variants aren't really the same as open datatypes like exn.

Firstly the typechecking for polymorphic variants is much weaker, i.e. the same variant can be used with any polymorphic variant type.

Secondly it is not possible to create a reference to a proper open polymorphic variant, while references to exn are allowed.

And lastly it is not possible to create local polymorphic variants, along the same lines as a local exception.

Regards,

Leo


On Jul 14 2011, Markus Mottl wrote:

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,  <[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



--
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

Reply via email to