Hi, Thank you all for your help! I think we're almost there: with Wolfgang's suggestion, the Node module complies with the original constraints, as the code below shows: (the compiler complains -- as it should! -- when on the last line I try to nest two link nodes directly)
module rec Node: sig type nonlink_node_t = [ `Text of string | `Bold of Node.super_node_t list ] type link_node_t = [ `See of string | `Mref of string * nonlink_node_t list ] type super_node_t = [ nonlink_node_t | link_node_t ] val text: string -> nonlink_node_t val bold: [< super_node_t] list -> nonlink_node_t val see: string -> link_node_t val mref: string -> nonlink_node_t list -> link_node_t end = struct type nonlink_node_t = [ `Text of string | `Bold of Node.super_node_t list ] type link_node_t = [ `See of string | `Mref of string * nonlink_node_t list ] type super_node_t = [ nonlink_node_t | link_node_t ] let text txt = `Text txt let bold seq = `Bold (seq :> super_node_t list) let see ref = `See ref let mref ref seq = `Mref (ref, seq) end open Node let foo1 = text "foo" (* valid *) let foo2 = bold [text "foo"] (* valid *) let foo3 = mref "ref" [text "foo"] (* valid *) let foo4 = mref "ref" [see "ref"] (* invalid *) Now, the icing on the cake would be the possibility to build a Node_to_Node set of functions without code duplication. Ideally, I would like to do something as follows: module Node_to_Node = struct open Node let rec convert_nonlink_node = function | `Text txt -> Node.text txt | `Bold seq -> Node.bold (List.map convert_super_node seq) and convert_link_node = function | `See ref -> Node.see ref | `Mref (ref, seq) -> Node.mref ref (List.map convert_nonlink_node seq) and convert_super_node node = match node with | #nonlink_node_t -> (convert_nonlink_node node :> super_node_t) | #link_node_t -> (convert_link_node node :> super_node_t) end But this fails on the last line: Error: This expression has type [< `Bold of 'a list & Node.super_node_t list | `Text of string ] as 'a but is here used with type [< `Mref of string * 'a list | `See of string ] These two variant types have no intersection Do you see any way around it? Thanks again for all your time and attention! Cheers, Dario __________________________________________________________ Not happy with your email address?. Get the one you really want - millions of new email addresses available now at Yahoo! http://uk.docs.yahoo.com/ymail/new.html _______________________________________________ Caml-list mailing list. Subscription management: http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list Archives: http://caml.inria.fr Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs