caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Dario Teixeira <darioteixeira@yahoo.com>
To: Jeremy Yallop <jeremy.yallop@ed.ac.uk>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Troublesome nodes
Date: Wed, 16 Jul 2008 14:22:21 -0700 (PDT)	[thread overview]
Message-ID: <461146.29236.qm@web54602.mail.re2.yahoo.com> (raw)
In-Reply-To: <487BAB0B.6030000@ed.ac.uk>

Hi,

> The first problem is that phantom types must be implemented in terms
> of abstract (or at least generative) types.  A simple example to
> illustrate the problem: the types
> 
>      int t
> and
>      float t
> 
> denote the same type given the alias declaration
> 
>      type 'a t = unit
> 
> but different types given the abstract type declaration
> 
>      type 'a t
> 
> The clause "= private 'a" in your declaration above indicates that `t'
> denotes an alias, not an abstract type.

What mislead me was a simple experiment I made where declaring 't' private
had the same effect as making it abstract for purposes of creating
module values (thus forcing you to constructor functions), while at
the same time keeping the 't' open for purposes of pattern-matching.
Suppose you have a simple module that prevents the user from mixing the
proverbial apples and oranges:

module Fruit:
sig
        type 'a t

        val apples: int -> [`Apples] t
        val oranges: int -> [`Oranges] t
        val (+): 'a t -> 'a t -> 'a t
end =
struct
        type 'a t = int

        let apples n = n
        let oranges n = n
        let (+) = (+)
end

open Fruit
let foo = apples 10
let bar = oranges 20
let sum = foo + bar  (* oops! *)


Now, if you un-abstract 't' by declaring "type 'a t = int" in the sig,
then the rogue unification makes the compiler accept the erroneous
top-level statements.  However, if instead you declare it as "type
'a t = private int", then rogue unification is prevented, but the type
is not completely hidden.  You can thus have your cake and eat it too.
(Please correct me if my interpretation of 'private' is off).


> Weak (ungeneralised) type variables are not allowed at module-level
> bindings.  You'll see a similar error message if you try to compile a
> module containing the following binding, for example
> 
>     let x = ref None
> 
> The solution to this problem is usually to change the form of the
> offending expression, for example by eta-expanding a term denoting a
> function.  In your case, though, the solution is to change the
> declaration of the abstract type `t' to indicate that the type
> parameters do not occur negatively in the right-hand side.  This takes
> advantage of a novel feature of OCaml -- the "relaxed value
> restriction" -- which uses a subtype-based analysis rather than a
> simple syntactic check to determine whether bindings can be made
> polymorphic.

Thanks for the explanation.  The solution I adopted was to use the
'+' covariance modifier (is that its name?) *only* for parameter 'a,
because parameter 'b should always be "terminated" via a make_basic or
make_complex function:  (there is no equivalent "termination" function
for parameter 'a because I want to allow documents to be composed from
other documents adlib).

type (+'a, 'b) t constraint 'a = [< super_node_t ]
val make_basic: ('a, [< `Basic]) t -> ('a, [`Basic]) t
val make_complex: ('a, [< `Basic | `Complex]) t -> ('a, [`Complex]) t

Also, I found it is alright to use ungeneralised type variables in
intermediate expressions, as long as the final expression generalises it:
(this is actually analogous to what happens when you declare "let x = ref
None"; it is fine as long as sooner or later you make the type concrete)

let doc =
	let n1 = bold [text "hello"] in		(* 'b is weak *)
	let n2 = mref "ref" [n1] in		(* 'b is still weak *)
	make_complex n2				(* 'b is now concrete *)

Cheers,
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


  reply	other threads:[~2008-07-16 21:22 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-11 20:39 Dario Teixeira
2008-07-11 21:20 ` [Caml-list] " Jeremy Yallop
2008-07-12 12:37   ` Dario Teixeira
2008-07-12 13:25     ` Jacques Carette
2008-07-12 16:44     ` Wolfgang Lux
2008-07-12 18:21       ` Dario Teixeira
2008-07-12 18:27         ` Jeremy Yallop
2008-07-12 18:58       ` Jacques Carette
2008-07-11 23:11 ` Zheng Li
2008-07-13 14:32 ` [Caml-list] " Dario Teixeira
2008-07-13 17:39   ` Dario Teixeira
2008-07-13 21:10     ` Jon Harrop
2008-07-14 15:11       ` Dario Teixeira
2008-07-14 18:52         ` Dario Teixeira
2008-07-14 19:37           ` Jeremy Yallop
2008-07-16 21:22             ` Dario Teixeira [this message]
2008-07-17  0:43             ` Jacques Garrigue
2008-07-17 10:59               ` Jeremy Yallop
2008-07-18  2:34                 ` Jacques Garrigue
2008-07-18  9:47                   ` Jeremy Yallop
2008-07-18 13:02                     ` Jacques Garrigue
2008-07-18 13:55                       ` Jacques Garrigue
2008-07-19  2:15                         ` Jacques Garrigue
2008-07-17 16:12               ` Dario Teixeira
2008-07-18  2:27                 ` Jacques Garrigue
2008-07-18 13:09                   ` Dario Teixeira
2008-07-18 17:36                     ` Dario Teixeira
2008-07-19  2:23                       ` Jacques Garrigue
2008-07-19  8:43                         ` Dario Teixeira

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=461146.29236.qm@web54602.mail.re2.yahoo.com \
    --to=darioteixeira@yahoo.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=jeremy.yallop@ed.ac.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).