ocaml

Chaining clauses in a pattern match, how to add missing bindings


I have a type defined as such:

type quantity = 
    Value of int 
  | Direction of int * int
  | Vector of int * int * int

Later I have functions that operate on values of the latter two subtypes together:

match q with
| Direction(x, y)
| Vector(x, y, magnitude) ->

Is there some way of defining magnitude to be 0 if the first pattern is matched? I know that I can use let x, y, magnitude = match (...) to convert the type into a tuple, or combine Vector and Direction into one subtype, setting magnitude to 0 where appropriate. But I am looking for something concise.


Solution

  • You cannot bind add bindings to patterns ( match q with Direction(x,y) and m = 0 -> in fantasy syntax). However, in this case it seems as simple to define a magnitude function

    let magnitude = function
      | Direction _ | Value _-> 0 
      | Vector (_,_,m) -> m
    

    and then use it:

    match q with
    | Direction(x, y)
    | Vector(x, y, _) ->
      let magnitude = magnitude q in
      ...
    

    On the other hand, more often than note the need to generate magical values from variant is a sign that your type definition does not fit the underlying concept.

    For instance, why is the magnitude of a direction 0? Why do vectors have magnitude as a component? If the first two arguments of the vector variant are in fact a direction, why is that not apparent in the type?