caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: "Yaron M. Minsky" <yminsky@cs.cornell.edu>
To: Caml List <caml-list@inria.fr>
Subject: Re: [Caml-list] syntax of private constructors in CVS version
Date: 01 Jul 2003 06:37:07 -0400	[thread overview]
Message-ID: <1057055827.3405.0.camel@dragonfly.localdomain> (raw)
In-Reply-To: <200306301839.UAA20778@pauillac.inria.fr>

A couple of thoughts:

      * First, this seem

On Mon, 2003-06-30 at 14:39, Pierre Weis wrote:
> Hi Brian & all,
> 
> [Sketching the semantics of private types, this message is long.] 
> 
> > Private only works with new record types and sum types that you declared. 
> > Think about it. What would it mean to declare some set of polymorphic variant 
> > tags as "private"? 
> 
> You're absolutely right on your comments and explanation. However, I
> think we also need to explain the ideas beneath private types and
> their intended uses.
> 
> As you should already know, usual sum and product types in Caml
> correspond to the mathematical notion of free algebraic data
> structures. This is fairly useful and allows the modelization of a lot
> of common data structures in practical programming
> situations. However, besides the free algebra structures,
> mathematicians use a lot of non-free algebras (so-called structures
> defined via generators and relations). Private types aim at giving a
> way to modelize those non-free structures. Equivalenetly, you can
> think of private types as providing a way to implement types equipped
> with invariants, quotient structures (i.e. sets of equivalence classes
> for some equivalence relation on a free algebra), or data types with
> canonical normal forms.
> 
> As an example, consider a simple modelization of natural integers in
> unary notation:
> 
> type nat =
>    | Zero
>    | Succ of nat;;
> 
> The nat type is a regular sum type; a value of the nat type is either
> the constant constructor Zero (modelizing the integer 0) or
> constructed with any application of the constructor Succ to a nat
> value (Succ n modelizing the successor of n or n + 1). Hence, the nat
> type is adequate in the sense that it exactly modelizes the unary
> representation of positive integers. Nothing new here, and we can
> easily write a test to 0 as:
> 
> let is_zero = function
>   | Zero -> true
>   | _ -> false;;
> 
> Now, let's go one step further and imagine we modelize integers
> (either positive or negative). Even if a complex (adequate)
> modelization of those numbers using a regular Caml data type is not
> very complex, let's take, for the sake of explanation, a simple
> approach by generalizing the nat type; we simply add an extra Pred
> constructor to modelize negative integers: Pred n is the predecessor
> of n or n - 1:
> 
> type integer =
>    | Zero
>    | Succ of integer
>    | Pred of integer;;
> 
> Now, we can modelize all integers in unary notation but the integer
> type is no more adequate, in the sense that we have a problem of
> unicity of representation: a given number can be modelized by
> (infinitely) many distinct values of the integer data type. For
> instance, the terms Succ (Pred Zero) and Zero all represent the number
> 0. You may think that this is not a big problem but in fact it is very
> ennoying, because when writing a function over values of type integer,
> you must now pattern match a lot of patterns instead of the only one
> that canonically represents a given integer. For instance
> 
> let is_zero = function
>   | Zero -> true
>   | _ -> false;;
> 
> is no more the expected predicate. We must write something much more
> complex, for instance
> 
> let rec is_zero = function
>   | Zero -> true
>   | Succ (Pred n) -> is_zero n
>   | Pred (Succ n) -> is_zero n
>   | n -> false;;
> 
> (BTW: is this code now correct ?)
> 
> A private type will solve this problem. We define a module Integer
> whose interface defines the integer type as a private type equipped
> with functions that construct values in the different summands of the
> type:
> 
> type integer = private
>    | Zero
>    | Succ of integer
>    | Pred of integer;;
> 
> value zero : unit -> integer
> value succ : integer -> integer
> value pred : integer -> integer
> 
> In the implementation of the module, we keep the definition of the
> type as regular (say ``public'', if you want) and implement the
> constructing functions such that they ensure the unicity of
> representation of integers:
> 
> let zero () = Zero;;
> 
> let succ = function
>   | Pred n -> n
>   | n -> Succ n;;
> 
> let pred = function
>   | Succ n -> n
>   | n -> Succ n;;
> 
> It is now easy to prove that all the integers built with applications
> of functions pred and succ have a unique representation (or
> equivalently that no tree of type integer obtained by composing those
> functions can have an occurrence of the redexes (Pred (Succ ...)) or
> (Succ (Pred ...))).
> 
> Now, since all the clients of the Integer module cannot construct
> values of type integer by directly applying the constructors and must
> use the constructing functions instead, we know for sure that the
> unicity property holds. Hence, the naive (and natural) version of
> is_zero is correct again.
> 
> In conclusion: private types serve to modelize types with arbitrary
> algebraic invariants (no miracle here: you must program those
> invariants in the definition of the constructing functions).
> 
> In contrast with abstract data types, the private types still maintain
> the elegant pattern matching facility of ML outside the module that
> defines the type.
> 
> Hope this helps.
> 
> Pierre Weis
> 
> INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/
> 
> 
> -------------------
> To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
> Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
-- 
|--------/            Yaron M. Minsky              \--------|
|--------\ http://www.cs.cornell.edu/home/yminsky/ /--------|

Open PGP --- KeyID B1FFD916 (new key as of Dec 4th)
Fingerprint: 5BF6 83E1 0CE3 1043 95D8 F8D5 9F12 B3A9 B1FF D916



-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners


  parent reply	other threads:[~2003-07-01 10:37 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-06-27 20:50 Shaddin Doghmi
2003-06-27 21:15 ` brogoff
2003-06-27 22:10   ` Shaddin Doghmi
2003-06-28  2:24     ` brogoff
2003-06-30 18:39       ` Pierre Weis
2003-06-30 19:00         ` Chris Hecker
2003-06-30 21:36           ` brogoff
2003-07-01 10:47           ` Pierre Weis
2003-07-01  7:43         ` Hendrik Tews
2003-07-01 10:37         ` Yaron M. Minsky [this message]
2003-07-01 10:51         ` Yaron M. Minsky
2003-07-01 17:05           ` Pierre Weis
2003-07-01 17:20             ` brogoff
2003-07-03 11:46         ` John Max Skaller
2003-07-07 22:31           ` Pierre Weis
2003-07-13  9:11             ` John Max Skaller
2003-07-15  8:02               ` Laurent Vibert
2003-07-15  8:22                 ` Pierre Weis

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=1057055827.3405.0.camel@dragonfly.localdomain \
    --to=yminsky@cs.cornell.edu \
    --cc=caml-list@inria.fr \
    /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).