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
next prev parent 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