(For educational purposes) I defined the following functions:
Translation (in $\mathbb{R}^2$):
trM[vec_] := {{1, 0, vec[[1]]}, {0, 1, vec[[2]]}, {0, 0, 1}}
Rotation (in $\mathbb{R}^2$):
rotM[angle_] := {{Cos[angle], -Sin[angle], 0}, {Sin[angle], Cos[angle], 0}, {0, 0, 1}}
Rotation around a point (in $\mathbb{R}^2$):
rotM[pt_, angle_] := trM[pt].rotM[angle].trM[-pt]
So far so good, now I want a function:
rotM[angle_, n_] :=
{{Cos[n angle], -Sin[n angle], 0}, {Sin[n angle], Cos[n angle], 0}, {0, 0, 1}}
Now
rotM[angle_, n_]
and
rotM[pt_, angle_]
share — in Mathematica — the same signature, which breaks the polymorphism I intended to use, which then leads to the following question.
How can I type-check the arguments of a Mathematica function to enforce polymorphism?
Answer
At a minimal level you could discriminate like this
f[angle_ n_] := ...
f[pt : {_, _}, angle_] := ...
But if you want to be really picky, you could limit your pt
argument to only except a list of two elements, both of which are numeric objects, but neither of which is a complex number. This can be done by defining a new argument pattern
pt2D = {Repeated[Except[_Complex, _?NumericQ], {2}]};
and using the pattern in a function definition such as
f[v : pt2D] := v
then
pts = {{1, 2}, {1., 2.}, {1., 2}, {1, π}, 1, {1}, {1, I}, {1, 2, 3}};
f /@ pts
gives
{{1, 2}, {1., 2.}, {1., 2}, {1, π}, f[1], f[{1}], f[{1, I}], f[{1, 2, 3}]}
Note both the wide acceptance of forms that have the structure of 2D points and the rejection of forms that don't.
Comments
Post a Comment