I have come to love this syntax in OCaml
match myCompare x y with
|Greater->
|Less->
|Equal->
However, it needs 2 things, a custom type, and a myCompare function that returns my custom type.
Would there be anyway to do this without doing the steps above?
The pervasives module seems to have 'compare' which returns 0 if equal, pos int when greater and neg int when less. Is it possible to match those? Conceptually like so (which does not compile):
match myCompare x y with
| (>0) ->
| (0) ->
| (<0) ->
I know I could just use if statements, but pattern matching is more elegant to me. Is there an easy (if not maybe standard) way of doing this?
Is there an easy … way of doing this?
No!
The advantage of match
over what switch
does in another language is that OCaml's match
tells you if you have thought of covering all the cases (and it allows to match in-depth and is compiled more efficiently, but this could also be considered an advantage of types). You would lose the advantage of being warned if you do something stupid, if you started using arbitrary conditions instead of patterns. You would just end up with a construct with the same drawbacks as a switch
.
This said, actually, Yes!
You can write:
match myCompare x y with
| z when (z > 0) -> 0
| 0 -> 0
| z when (z < 0) -> 0
But using when
makes you lose the advantage of being warned if you do something stupid.
The custom type type comparison = Greater | Less | Equal
and pattern-matching over the three only constructors is the right way. It documents what myCompare
does instead of letting it return an int
that could also, in another language, represent a file descriptor. Type definitions do not have any run-time cost. There is no reason not to use one in this example.
You can use a library that already provide those variant-returning compare functions. This is the case of the BatOrd module of Batteries, for example.
Otherwise your best bet is to define the type and create a conversion function from integers to comparisons.
type comparison = Lt | Eq | Gt
let comp n =
if n < 0 then Lt
else if n > 0 then Gt
else Eq
(* ... *)
match comp (Pervasives.compare foo bar) with
| Lt -> ...
| Gt -> ...
| Eq -> ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With