OCaml order of pattern matches best practice

ocaml, pattern-matching

Solution

Pattern matching algorithms in OCaml are very clever, so that you don't need to bother about order of matches. Start reading from this stackoverflow post if you're interested in a subject.

There're some exception to the above rule: first, the semantics of your function may depend on the order of matches, if they overlap; second, if you pattern match on data, like strings, or integers then it will be compiled to somewhat resembling `if/else` series, with some optimizations.

And finally asking the original question, there is no known to me best practices on how to write pattern-matches in efficient way.

Update:

Just in case, I obviously think that the provided example is synthetic, but for those who will read us in future. You don't need to write this function at all, as pervasive's `min` is universally polymorphic function already has the expected behavior on options. So your function is doing exactly the same (semantically) as `min x y`. But, if you're really interested in optimization, for example, if you're using this in a tight loop, then you can rewrite it like this:

let min x y : int option =
  match x, y with
  | v, None | None, v -> v
  | Some p, Some q -> if p < q then x else y

That will yield out an effective code, that will not perform a C-call to polymorphic comparison function, and do not perform any allocations. But as always, you should trace your program to figure out, that this function is indeed a bottleneck.

Problem

From a performance standpoint, I was wondering if the order of patterns matched affects the efficiency of the function, or it has more to do with the proportion of different matches expected (i.e. if one pattern happens way more than the others, it should appear earlier). ``` (* a function to return the smaller of two int options, or None if both are None. If exactly one argument is None, return the other. *) let min_option (x: int option) (y: int option) : int option = match x, y with None, None -> None | Some x, None -> Some x | None, Some y -> Some y | Some x, Some y -> if x < y then Some x else Some y let () = assert((min_option (Some 10) (Some 11)) = Some 10);; ```

Original source

Related problems