Version française
Home     About     Download     Resources     Contact us    
Browse thread
Troublesome nodes
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Dario Teixeira <darioteixeira@y...>
Subject: Re: [Caml-list] Troublesome nodes
Hi,

Thanks once more for your help, Jacques.  I had no idea this problem would
prove to be such a challenge!


> So if you write
>
>  type (+'a, 'b) t = private 'a constraint 'a = [< super_node_t ]
>
> then you must write (x : (_,_) t :> [> ]) if you want to use pattern
> matching on x.


The 'private' declaration you suggested does work on some simpler examples,
but the 3.11 compiler won't accept it for the Node module.  This is the code:

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: ('a, [< `Basic]) t -> ('a, [`Basic]) t
        val make_complex: ('a, [< `Basic | `Complex]) t -> ('a, [`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
        let make_complex n = n
end

And this is the error:

 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 ]


> By the way, I forgot to mention that aliases (as keyword) of those
> were not allowed until now, so I have to fix it to make the syntax for
> private rows work. (There are useful examples using this syntax.)
>
>  type ('a, 'b) t = private [< super_node_t ] as 'a

With 3.11+dev12, the above declaration produces a "Unbound type parameter .."
error.  When you say you have to fix it, do you mean this will actually be
a valid declaration in 3.11 final?  And will this solution allow for easier
pattern-matching of Node values, without the need for coercion?

Speaking of coercion, the exact syntax for it in combination with '#'
patterns elludes me.  Take for example a simple, "identity", Node-to-Node
module listed below.  How can coercion be applied?


module Node_to_Node =
struct
    open Node

    let rec convert_nonlink_node = function
        | `Text txt                     -> text txt
        | `Bold inl                     -> bold (List.map convert_super_node inl)

    and convert_link_node = function
        | `Mref (ref, inl)              -> mref ref (List.map convert_nonlink_node inl)
        | `See ref                      -> see ref

    and convert_super_node = function
        | #nonlink_node_t as node       -> (convert_nonlink_node node : ('a, 'b) t :> (super_node_t, 'b) t)
        | #link_node_t as node          -> convert_link_node node
end


Best regards,
Dario Teixeira



      __________________________________________________________
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