Browse thread
Phantom types: transparency vs rogue unification
-
Dario Teixeira
-
Jacques Carette
-
Dario Teixeira
- Dario Teixeira
-
Dario Teixeira
-
Jacques Carette
[
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: | -- (:) |
| 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