caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Markus Mottl <mottl@miss.wu-wien.ac.at>
To: Chris.Keane@comlab.ox.ac.uk (Chris Keane)
Cc: caml-list@inria.fr (OCAML)
Subject: Re: Constructed types
Date: Thu, 21 Jan 1999 02:22:38 +0100 (MET)	[thread overview]
Message-ID: <199901210122.CAA19976@miss.wu-wien.ac.at> (raw)
In-Reply-To: <199901201042.KAA01535@msc2.comlab> from "Chris Keane" at Jan 20, 99 10:42:18 am

Hello,

> then why doesn't this?
> 
>   > # let myfun2 x =
>   >     let m = if x = 0 then (0,0) else (1,1) in
>   >       Bar m;;
>   > The constructor Bar expects 2 argument(s),
>   > but is here applied to 1 argument(s)

I have also come across this problem when porting Okasaki's sources from
SML to OCAML - obviously, this restriction does not apply to SML.

E.g. (taken from a pattern match in function "balance" in the
      implementation of red-black trees):

  | ...
  | body = T body

body should actually be of type tree:

type tree  = E | T of color * tree * elem * tree

But although the preceding patterns already indicate the only possible
type, one cannot just simply match the tuple with one identifier and
place it after the non-constant constructor. One would have to write
something like

  | ...
  | a,b,c,d -> T (a,b,c,d)

I have tried to find something about that in the reference manual, but
found only this (I hope it's relevant):

  The expression ncconstr expr evaluates to the variant value whose
  constructor is ncconstr, and whose argument is the value of expr.

If I interpret this right, a non-constant constructor should work with
any expression (that matches, of course). I don't know, why this does
not apply here.  Since it is possible to do this in SML, I really wonder,
whether there is some special reason to it.

Because it somehow fits into this question, here another problem I have
come across in the same function.

The working version looks like this:

  let balance = function
      B,T (R,T (R,a,x,b),y,c),z,d -> T (R,T (B,a,x,b),y,T (B,c,z,d))
    | B,T (R,a,x,T (R,b,y,c)),z,d -> T (R,T (B,a,x,b),y,T (B,c,z,d))
    | B,a,x,T (R,T (R,b,y,c),z,d) -> T (R,T (B,a,x,b),y,T (B,c,z,d))
    | B,a,x,T (R,b,y,T (R,c,z,d)) -> T (R,T (B,a,x,b),y,T (B,c,z,d))
    | a,b,c,d                     -> T (a,b,c,d)

Now, Okasaki claims that in Standard ML of New Jersey it is possible
to rewrite this as (I use OCAML syntax otherwise and do as if the first
problem presented here did not exist):

  let balance = function
      B,T (R,T (R,a,x,b),y,c),z,d 
    | B,T (R,a,x,T (R,b,y,c)),z,d
    | B,a,x,T (R,T (R,b,y,c),z,d) 
    | B,a,x,T (R,b,y,T (R,c,z,d)) -> T (R,T (B,a,x,b),y,T (B,c,z,d))
    | body                        -> T body

This looks really readable now. But if I do this in OCAML, the compiler
will complain that variables are bound several times in this matching -
they are obviously already bound *before* the multiple match (which is
otherwise possible) is over.

I am not sure whether this feature found in SML/New Jersey creates more
problems than it solves (e.g. what if values bound to the same identifier
have different types in the pattern?). But in this specific function
it comes really handy. At least there doesn't seem to be a good reason,
why names should be bound in other patterns before they can be used on
the right-hand side.

Best regards,
Markus

-- 
Markus Mottl, mottl@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl




  reply	other threads:[~1999-01-21 15:23 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1999-01-20 10:42 Chris Keane
1999-01-21  1:22 ` Markus Mottl [this message]
1999-01-21 15:37 Toby Moth
1999-01-21 16:05 Markus Mottl

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=199901210122.CAA19976@miss.wu-wien.ac.at \
    --to=mottl@miss.wu-wien.ac.at \
    --cc=Chris.Keane@comlab.ox.ac.uk \
    --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).