I'm a big fan of using conditionals inside my functions to deal with cases, that is, to pattern match in stages and possibly leave a function unevaluated.
In[1]:= f[x_] :=
(
(
(
True
) /; EvenQ[x]
) /; x > 2
) /; x < 10
In[2]:= f[4]
Out[2]= True
However I don't fully understand the extent to which I can do this. For example, mixing If statements in doesn't work:
In[3]:=
h[x_] :=
(
If[x > 2,
(
True
) /; EvenQ[x]
,
False
]
) /; x < 10
In[4]:= h[4]
Out[4]= True /; EvenQ[4]
A clarification on both the limitation and merits of this style of coding would be helpful.
I find this style of programming to be handy for a number of reasons, but a primary reason is the ease of defining a blanket default case and letting the pattern matching do its work, e.g. f[_] := $Failed
.
Answer
I think the general notion here is that conditional patterns x_/;EvenQ[x]
and conditional expressions If[EvenQ[x],a,b]
are not the same thing. In your first example, you nest conditional patterns in the definition of f which means that all the conditions have to be true for a match against the pattern to be successful. In the second, only the outermost condition is actually used in the definition of h, and it assumes you want your returned expression from the True case of If[x>2,...]
to return a conditional pattern when x>2
. which is what you get, the conditional pattern True /; EvenQ[4]
. This pattern matches against True, so MatchQ[True, True /; EvenQ[4]]
would return True
.
If I understand your intention correctly the second function would be defined as:
h[x_ /; (EvenQ[x] && x < 10)] := If[x > 2, True, False]
Note that I have kept all the conditional patterns on the left, and return a conditional expression, which evaluates depending on x.
Comments
Post a Comment