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.
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?