Version française
Home     About     Download     Resources     Contact us    
Browse thread
Phantom types: transparency vs rogue unification
[ 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] Phantom types: transparency vs rogue unification
Hi,

I may have spoken too soon about the functor solving the problem.  In fact,
in a non-trivial example the problem is merely shifted to a different place.

Consider thus the basic document below; note that the phantom type is made
opaque in the signature, thus preventing the rogue unification we wish to
avoid at all cost:

_____________________________________________________________________
module type DOCUMENT =
sig
        type inline_t = node_t list
         and node_t =
                private
                | Text of string
                | Bold of inline_t
                | Italic of inline_t

        type 'a t

        val text: string -> [> `Basic] t
        val bold: 'a t list -> 'a t
        val italic: [< `Basic | `Complex] t list -> [> `Complex] t
end


module Document: DOCUMENT =
struct
        type inline_t = node_t list
         and node_t =
                | Text of string
                | Bold of inline_t
                | Italic of inline_t

        type 'a t = node_t

        let text str = Text str
        let bold inl = Bold inl
        let italic inl = Italic inl
end
_____________________________________________________________________


Let us now try to extend the basic type with a couple of parsing functions.
Simpy using "include" will fail, because the signature DOCUMENT has made
Document.t opaque.  I thought the solution could come from the "with type"
directive:

_____________________________________________________________________
module type DOCUMENT_PARSER =
sig
        include DOCUMENT

        exception Invalid_Subset

        val parse_complex: string -> [> `Basic | `Complex] t
        val parse_basic: string -> [> `Basic] t
end

module Document_parser: DOCUMENT_PARSER with type 'a t = Document.node_t =
struct
        include Document

        exception Invalid_Subset

        let parse_complex = function
                | "complex"     -> italic [text "foo"]
                | _             -> bold [text "bar"]

        let rec complex_to_basic = function
                | Text str      -> text str
                | Bold inl      -> bold (List.map complex_to_basic inl)
                | Italic inl    -> raise Invalid_Subset

        let parse_basic str = complex_to_basic (parse_complex str)
end
_____________________________________________________________________


But unfortunately something else must me missing, because the compiler
complains on the one-before-last line:

Error: This expression has type
         ([> `Basic | `Complex ] as 'a) t = 'a Document.t
       but is here used with type node_t = Document.node_t


I have also tried the functor-based approach, but the same error happens.
Any ideas on how to solve this?  Or could this be one of those cases where
only the object system can help?

Thanks in advance for your time!

Kind 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