caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: John Prevost <j.prevost@cs.cmu.edu>
To: Dan Schmidt <dfan@dfan.org>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Design advice
Date: 28 Sep 2002 06:48:58 -0400 (45.067 UMT)	[thread overview]
Message-ID: <86y99mqtid.fsf@laurelin.dementia.org> (raw)
In-Reply-To: <ud6qznzvc.fsf@dfan.thecia.net>

>>>>> "ds" == Dan Schmidt <dfan@dfan.org> writes:

    ds> {...} it seems weird to perform
    ds> pattern matching on values that really have no semantic
    ds> importance other than the fact that they are different from
    ds> each other.  It's not like I'm going to have any code that
    ds> does one thing when given the 3 of Spades and another thing
    ds> when given the 3 of Hearts.  The other issue is that it is
    ds> mildly annoying to, for example, write a compare function to
    ds> be used inside a struct that implements the OrderedType
    ds> signature (e.g., if I want to have a Set of cards).

Well, note that in the type you've defined, the only thing in the type
is the different suits.  That is the *only* information there.  I
don't see why it seems unreasonable to pattern match here.

Note that the built-in comparison operations work just fine on types
defined this way.

    ds> {... similar angst about Player_One and Player_Two ...}

In this case, it only makes sense in games with precisely two players.
For example: Go, or Chess.  If you think you might be using an array
that you want to index into, you may very well be thinking of a game
with unbounded numbers of players--or a library for unbounded numbers
of players.  (For example, Bridge has only four players, but a more
general library for hands of cards might support an arbitrary number.)

In the case of a set number of players, you might use a tuple instead
of an array, since you know the precise size, and you know which
player goes with which item.  As an example:

type player = North | South | East | West
type state = { n_hand : hand, s_hand : hand, e_hand : hand, w_hand : hand }

let get_hand p st = match p with
  | North -> st.n_hand
  | South -> st.s_hand
  | East -> st.e_hand
  | West -> st.w_hand

Is this a little heavy?  Well, possibly.  But it's not unreasonable,
and it does at the very least restrict possible "unsafe" operations to
certain sections of code.  You might, for example, do this instead of
the above:

type player = (* same *)
type state = hand array

let player_to_index = function
  | North -> 0
  | South -> 1
  | East -> 2
  | West -> 3

let get_hand p st = st.(player_to_index p)

And don't export player_to_index or the structure of the state type.
Now the "unsafe" region of your code is just in the library that
contains the above.  Anything that uses it manipulates things purely
in terms of the bounded type, and you only have to verify that
indexing works right in the above library.

When in doubt, export the safest interface possible and then ensure
that your module's internals are correct.  That way you have at least
ensured that users of your module cannot feed you bad arguments.

    ds> Finally, is there any type in the library that functions like
    ds> an immutable array?  I would like to have an indexable bunch
    ds> of values but use it in a purely functional way.  I could
    ds> always just use Arrays and copy them before updating, but if
    ds> there's already an idiomatic type to use I'd prefer to use
    ds> that.

There is none in the base O'Caml.  But this might be more efficient
than copying all the time:

http://www.ai.univie.ac.at/~markus/home/ocaml_sources.html

Take a look in 4.1.6 (Okasaki's Purely Functional Datastructures in
OCaml), chp9.ml, and look at the random access lists.
-------------------
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


  reply	other threads:[~2002-09-28 10:48 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-27 16:47 Dan Schmidt
2002-09-28 10:48 ` John Prevost [this message]
2002-09-28 10:55 ` Chris Hecker
2002-09-28 19:02   ` William Lovas
2002-09-28 22:01     ` John Gerard Malecki
2002-09-28 23:03       ` Chris Hecker
2002-09-30 15:35       ` Kontra, Gergely
2002-09-28 22:46     ` Chris Hecker
2002-09-29 12:27 ` Lauri Alanko
2002-09-30 16:03   ` Alessandro Baretta
2002-10-01 11:37 ` Xavier Leroy

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=86y99mqtid.fsf@laurelin.dementia.org \
    --to=j.prevost@cs.cmu.edu \
    --cc=caml-list@inria.fr \
    --cc=dfan@dfan.org \
    /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).