printf ( "%d 23", Accelerate );; (* sorry if my syntax is off, I haven't
gotten too far with it yet *)
where "Accelerate" evaluates to an int.
On Wed, Jun 13, 2001 at 09:37:12AM +0200, David Mentre wrote:
> sum type and pattern matching is really what you are looking for:
> What's the right way to make something like C's enums in OCaml. I found a
> couple references to sum types online and in the manual and caml light
> tutorial, but none of it was really what I'm looking for: alias a number
> with a name, hopefully conveniently.
sum type and pattern matching is really what you are looking for:
# type my_enum = Case1 | Case2 | Case3;;
type my_enum = Case1 | Case2 | Case3
# let num c = match c with Case1 -> 1 | Case2 -> 2 | Case3 ->3 ;;
val num : my_enum -> int = <fun>
# num Case3;;
- : int = 3
Usually, you do not need to call the num function, you can use the
symbolic name directly in your code. And at the opposite of C enum, if a
case is forgotten, the compiler warns you (usefull when you extend your
enum):
# let faulty_num c = match c with Case1 -> 1 | Case2 -> 2;;
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
Case3
val faulty_num : my_enum -> int = <fun>
Best regards,
d.
--
David....@inria.fr -- http://www.irisa.fr/prive/dmentre/
Opinions expressed here are only mine.
> I'm looking for something that would do the right thing when I do:
>
> printf ( "%d 23", Accelerate );; (* sorry if my syntax is off, I haven't
> gotten too far with it yet *)
Probably something like:
# type enum = Accelerate | Other;;
type enum = Accelerate | Other
# let int_enum e =
match e with
| Accelerate -> 1
| Other -> 0;;
val int_enum : enum -> int = <fun>
# Printf.printf "%d 23\n" (int_enum Accelerate);;
1 23
- : unit = ()
But without further context, it is difficult to guess what you want
(i.e. do the right thing).
Maybe you should have a look at source code of standard libraries. They
are remarkably concise and well written.
For example, operations on lists (List module):
http://camlcvs.inria.fr/cgi-bin/cvsweb.cgi/ocaml/stdlib/list.ml?rev=1.27&content-type=text/x-cvsweb-markup
d.
--
David....@inria.fr -- http://www.irisa.fr/prive/dmentre/
Opinions expressed here are only mine.
On Wed, Jun 13, 2001 at 10:46:36AM +0200, David Mentre wrote:
> Maybe you should have a look at source code of standard libraries. They
> are remarkably concise and well written.
Thanks for the link, I'd passed that over (!) as a reference for examples.
Which brings up a question: Is there anyone working on annotating the
standard/core libraries. Might do for OCaml a bit of the magic that the
classic work did for Unix and C (I forget the title/author; someone?).
> For example, operations on lists (List module):
> http://camlcvs.inria.fr/cgi-bin/cvsweb.cgi/ocaml/stdlib/list.ml?rev=1.27&content-type=text/x-cvsweb-markup
let message_to = function
"accel" -> 1
| "stop" -> 0
| _ -> -1;;
...which is perhaps less typing/editing up front, but a bit of a pain to
type all the "s in the code.
So, what's so wrong with just using variables?
let Accel = 1;;
let Stop = 0;;
seems pretty short to write and shortest to use... Am I missing something
( elegant | obvious )? Is that just ugly?
thanks
You can't pattern match on variables (even constant nonmutable ones like that). See the list archives for threads about this.
You have to do this:
match value with
| v when v = accel -> blah
| v when v = stop -> etc
Not very pretty.
If you're going to be using them in code a lot, then I'd just use variants (sum types). Yes, it'd be best to be able to switch on the constants, but this is apparently hard; see the archive.
Chris
If you use sum types, the compiler will
* check that in any pattern matching, or collection of objects
(e.g. list), you only use constructors of the same sum type
* check whether your pattern matches are exhaustive or not, and avoid
adding a default "_ -> .." clause at the end
These two checks take something like half of the bugs in any
program. So yes, this is paramount to use sum types rather than named
constants. The only case you want to use named constants is when you
do not have an exhaustive list of cases available, and want to be able
to add cases afterwards, making the above checks impossible. Even in
this case you may want to go for hybrid solutions, including a sum
type for the cases you know, but this is a bit more high-level.
Jacques Garrigue
I wouldn't like to be patronising in this, so please forgive if I don't use as many
emoticons as I should be doing... ;)
le...@nwlink.com wrote:
> So, what's so wrong with just using variables?
>
> let Accel = 1;;
> let Stop = 0;;
>
> seems pretty short to write and shortest to use... Am I missing something
> ( elegant | obvious )? Is that just ugly?
I gather you are learning the language... If it is because you want to try
something new or want to check some of the publicised "good" qualities of FP, why
don't you try to code your type in *both* styles, one using constants and the other
sum types and then make a better-informed decision?
As long as you are at it, also, why not make it into a tutorial for the coding of
such types? We seem to be short on tutorials in Ocaml...
Regards, and best of luck... I hope you see the light (and start coding in Ocaml!
:) )
Francisco Valverde
Univ. Carlos III de Madrid
There's mention of an SML extension that solves this problem (ie. retaining the good typing properties).
Are the Caml designers considering this?
Chris Q.