English version
Accueil     À propos     Téléchargement     Ressources     Contactez-nous    

Ce site est rarement mis à jour. Pour les informations les plus récentes, rendez-vous sur le nouveau site OCaml à l'adresse ocaml.org.

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: 2008-06-26 (21:41)
From: Dario Teixeira <darioteixeira@y...>
Subject: Re: [Caml-list] Phantom types: transparency vs rogue unification

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 =
        type inline_t = node_t list
         and node_t =
                | 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

module Document: DOCUMENT =
        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

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"

module type DOCUMENT_PARSER =
        include DOCUMENT

        exception Invalid_Subset

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

module Document_parser: DOCUMENT_PARSER with type 'a t = Document.node_t =
        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)

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