caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Dario Teixeira <darioteixeira@yahoo.com>
To: Jacques Garrigue <garrigue@math.nagoya-u.ac.jp>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Private types in 3.11, again
Date: Wed, 21 Jan 2009 11:11:14 -0800 (PST)	[thread overview]
Message-ID: <361979.82701.qm@web111514.mail.gq1.yahoo.com> (raw)
In-Reply-To: <20090121.222217.31602828.garrigue@math.nagoya-u.ac.jp>

Hi,

Thank you very much for your help, Jacques!  It's always enlightening to
see an Ocaml ninja in action, though I'm still digesting the finer points
of your message.  Anyway, I have implemented all three solutions you suggested:

a) Using a private row and PV
b) Using a private abbreviation and PV
c) Using the mapper + object system with regular variants

Solution a) is by far the most convenient, though I'm still having some trouble
with it (more below).  Which brings me to a crucial point where I'm still
fuzzy.  My initial model for the link-nodes-shall-not-be-ancestors-of-their-kin
problem did indeed rely on what I now realise are GADTs.  I ran into a
limitation of the type system and so I recast the model using phantom types
because I hoped they could provide a workaround.  So my question is whether it
is at all possible to emulate GADTs using only PV + phantom types, or if on the
contrary one needs to use the object system in these cases, as exemplified by
solution c).  In other words, is solution a) futile, or did you use the object
system in solution c) simply because you were also using regular variants?

As for the problem with solution a), it shows up when I implement outside
of module Node any non-trivial function operating on 'a Node.t.  Function
capitalise_node, for example:


module Node:
sig
	type 'a node_t =
		[ `Text of string
		| `Bold of 'a list
		| `Href of string
		| `Mref of string * 'a list
		]

	type +'a t = private [< 'b node_t ] as 'b

	val text: string -> [> `Nonlink ] t
	val bold: 'a t list -> 'a t
	val href: string -> [> `Link ] t
	val mref: string -> [< `Nonlink ] t list -> [> `Link ] t
end =
struct
	type 'a node_t =
		[ `Text of string
		| `Bold of 'a list
		| `Href of string
		| `Mref of string * 'a list
		]

	type +'a t = 'b node_t as 'b

	let text txt = `Text txt
	let bold seq = `Bold seq
	let href lnk = `Href lnk
	let mref lnk seq = `Mref (lnk, seq)
end


module Foobar:
sig
	val capitalise_node: 'a Node.t -> 'a Node.t
end =
struct
	let capitalise_node node =
		let rec capitalise_node_aux forbid_link node = match (forbid_link, node) with
			| (_, `Text txt)		-> Node.text (String.capitalize txt)
			| (x, `Bold seq)		-> Node.bold (List.map (capitalise_node_aux x) seq)
			| (false, `Href lnk)		-> Node.href lnk
			| (false, `Mref (lnk, seq))	-> Node.mref lnk (List.map (capitalise_node_aux true) seq)
			| _				-> failwith "this shouldn't happen"
		in capitalise_node_aux false node
end


The code above produces the compiler error below (though remember that this
same function works fine inside the Node module):

Error: This expression has type ([> `Link | `Nonlink ] as 'a) Node.t list
       but is here used with type ([< `Nonlink ] as 'b) Node.t list
       Type
         'a Node.t =
           [< `Bold of 'a Node.t list
            | `Href of string
            | `Mref of string * 'a Node.t list
            | `Text of string ]
       is not compatible with type
         'b Node.t =
           [< `Bold of 'b Node.t list
            | `Href of string
            | `Mref of string * 'b Node.t list
            | `Text of string ]
       The first variant type does not allow tag(s) `Link


Thanks again for all your time!
Best regards,
Dario Teixeira






  reply	other threads:[~2009-01-21 19:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-01-15 17:31 Dario Teixeira
2009-01-19 15:09 ` [Caml-list] " Dario Teixeira
2009-01-20 16:33   ` Dario Teixeira
2009-01-20 17:29     ` Jacques Carette
2009-01-20 17:48       ` Dario Teixeira
2009-01-21 10:48       ` Jacques Garrigue
2009-01-21 10:38     ` Jacques Garrigue
2009-01-21 13:22   ` Jacques Garrigue
2009-01-21 19:11     ` Dario Teixeira [this message]
2009-01-21 20:17       ` Gabriel Kerneis
2009-01-21 21:52         ` GADTs in Ocaml (was: Private types in 3.11, again) Dario Teixeira
2009-01-22  1:36       ` [Caml-list] Private types in 3.11, again Jacques Garrigue
2009-01-26 15:13 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=361979.82701.qm@web111514.mail.gq1.yahoo.com \
    --to=darioteixeira@yahoo.com \
    --cc=caml-list@yquem.inria.fr \
    --cc=garrigue@math.nagoya-u.ac.jp \
    /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).