Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I was looking at this Q&A about using pattern test (pattern_?test) vs pattern condition (pattern_/;cond) and came across this example where using condition was the only possible way to restrict the function parameters (function definition added by me):

Clear[fCond]
fCond[x__ /; Plus[x] == 7] := {x}^2
fCond[1, 2, 4]
(* {1, 4, 16} *)

I know that, aside from the built-in tests in MMA (IntegerQ, NumericQ, eg), one can write custom pattern tests using pure functions [2]:

test pure function

Hence, I was trying to be clever by using tests with sequence pattern (__) coupled with sequence argument for pure function (##). However, this did not work when plugging in values for the parameter/pattern.

Clear[fTest]
fTest[x__?(Plus[##] == 7 &)] := {x}^2
fTest[1, 2, 4]
(* fTest[1, 2, 4] *)

, even though the pure function test alone does work with the plugged in sequence

Plus[##] == 7 &[1, 2, 4]
(* True *)

Why doesn't pattern test work via this method? If so, is there any other way to do pattern test as opposed to pattern condition in this case?

[2]: Ruskeepaa's Mathematica Navigator 2009 p.498

share|improve this question
3  
Because in case of __?test the test is applied to each argument, not to the sequence as a whole. Try fTest[7, 7, 7]. I have learned it from your previous question btw :) –  Kuba Jul 6 at 9:47
1  
Your question contains so much extraneous material that I find it is hard to determine what you are really asking. In particular, in most cases we don't need images of your notebook cells. You can include evaluation results, except for graphics, using normal markdown formatting. –  m_goldberg Jul 6 at 15:00
2  
3rd line in the Details section of PatternTest: In a form such as __?test, every element in the sequence matched by must yield True when test is applied. –  Sjoerd C. de Vries Jul 6 at 21:28
    
Thanks for your suggestion @m_goldberg. I cleaned up my question per your recommendations. –  seismatica Jul 9 at 18:52
    
Thanks Kuba and Sjoerd C. de Vries! I wish I could accept both of your comments as answers. –  seismatica Jul 9 at 19:48

1 Answer 1

up vote 3 down vote accepted

My apologies to those who closed this question for my unilaterally reopening it, but there is a nontrivial aspect to this question that I wish to address, and it would not nicely fit in comments. (I am not making an exception for myself; when someone has such an answer he wishs to give to a closed question I nearly always reopen it for him to do so.)


While I stated before that: "I can think of no way to do this with PatternTest" was not speaking rigorously and generally, but rather one-to-one substitution of methods. One can apply PatternTest to a larger expression, e.g. the entire left-hand-side, as I did for your prior question. If handling the entire LHS one must exercise care to prevent infinite recursion. Here is an example of how that may be done:

SetAttributes[sumsTo7, HoldFirst]
sumsTo7[_[s__]] := +s == 7

f[x__]?sumsTo7 := {x}

Now:

f[1, 2]
f[3, 4]
f[1, 2]

{3, 4}

It is possible to do this with an anonymous Function as well but it becomes rather baroque:

g[x__]?(Function[Null, Plus @@ Unevaluated[#] == 7, HoldAll]) := {x}

g[1, 2, 3]
g[-3, 10]
g[1, 2, 3]

{-3, 10}
share|improve this answer
    
Thanks @Mr.Wizard. The +s looks rather neat! –  seismatica Jul 9 at 18:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.