[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2008-07-14 (18:52) |
From: | Dario Teixeira <darioteixeira@y...> |
Subject: | Re: [Caml-list] Troublesome nodes |
Hi, After some trial and error in the top-level, I think I got the hang of the 'constraint' declaration (is there other documentation for it besides the couple of lines in the Reference Manual?). Note that besides the already discussed link/nonlink distinction between nodes, there is now also an orthogonal distinction between basic/complex nodes (all nodes except for Mref are basic; any document that uses Mref thus becomes "contaminated" and cannot use basic-only functions; the inverse, however, is not true). I took advantage of Jon's suggestion of boxing all return types into a single Node.t to implement this latter distinction using phantom types (is there even an alternative technique?). Now, the code below seems correct, and running "ocamlc -i node.ml" produces the type signatures you would expect, and without error messages. However, running "ocamlc -c node.ml" fails with a "The type of this expression contains type variables that cannot be generalized" error on the declaration of foo3. Moreover, if you comment out the top-level declarations and try to compile only the module declaration, you will also get different results whether you run "ocamlc -i" or "ocamlc -c". The former displays the module's signature as expected, but the latter produces this error message: Type declarations do not match: type ('a, 'b) t = ('a, 'b) Node.t constraint 'a = [< super_node_t ] is not included in type ('a, 'b) t = private 'a constraint 'a = [< super_node_t ] I find this behaviour a bit odd. What is going on? Best regards, Dario Teixeira 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 ] type ('a, 'b) t = private 'a constraint 'a = [< super_node_t ] val text: string -> ([> nonlink_node_t], [> `Basic]) t val bold: ([< super_node_t], 'a) t list -> ([> nonlink_node_t], 'a) t val see: string -> ([> link_node_t], [> `Basic]) t val mref: string -> (nonlink_node_t, 'a) t list -> ([> link_node_t], [> `Complex]) t val make_basic: ([< super_node_t], [< `Basic]) t -> (super_node_t, [`Basic]) t val make_complex: ([< super_node_t], [< `Basic | `Complex]) t -> (super_node_t, [`Complex]) 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 ] type ('a, 'b) t = 'a constraint 'a = [< super_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) let make_basic n = (n :> (super_node_t, [`Basic]) t) let make_complex n = (n :> (super_node_t, [`Complex]) t) end open Node let foo1 = text "ola" let foo2 = bold [text "ola"] let foo3 = mref "ref" [foo1; foo2] let basic1 = make_basic foo1 let basic2 = make_basic foo2 let complex1 = make_complex foo1 let complex2 = make_complex foo2 let complex3 = make_complex foo3 __________________________________________________________ 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