# Pattern test for variables during function definition

I am having a problem with pattern testing on variables during function definition

nfun[M : Repeated[_?(test1&&test2||test3..)&, {10}]]:= N@(Norm@(Sin[#] & /@ M))


I want to have a few tests on the vectors M that I want to feed nfun. One example that does not work if I want to test if M has Integer entries using Repeated is the following.

nfun[M : Repeated[_?IntegerQ, {10}]]:= N@(Norm@(Sin[#] & /@ M))


Here goes another filed trial with the same aim.

nfun[M_?((VectorQ[#, IntegerQ]) && (Length[#] == 10)) &]:= N@(Norm@(Sin[#] & /@ M))

-

nfun[M : Repeated[_IntegerQ, {10}]]:= N@(Norm@(Sin[#] & /@ M))


This does not work because _IntegerQ is testing an expression for the explicit head IntegerQ rather than Integer. Use _Integer or generically _?test.

For applying a series of tests I recommend:

f[M : Repeated[_Integer, {10}]] /; test1[M] && test2[M] || test[M] := {{M}}


Okay, I see that this is not identical to what you were constructing because of the difference between PatternTest and Condition. If your aim is to test every element separately it is usually cleanest to establish a single test function and use _?test. For example:

test = # < 8 && EvenQ[#] || PrimeQ[#] &;

f[M : Repeated[_?test, {10}]] := {{M}}

-
However nfun[M : Repeated[_Integer, {10}]] :=N@(Norm@(Sin[#] & /@ M)) does not work either if you try nfun[Range[10]] and same for the f you defined with the test. Try f[M : Repeated[_?test, {4}]] := {{M}}; test[#] & /@ {2, 4, 6, 13} which gives all true. But f[{2, 4, 6, 13}] does not evaluate! – PlatoManiac Jun 20 '12 at 15:54
+1 for a separate function - I agree that it is the cleanest way. – Leonid Shifrin Jun 20 '12 at 16:08
@PlatoManiac You're mixing your input types. Try : nfun @@ Range[10] or change you definition to account for List. – Mr.Wizard Jun 20 '12 at 16:10
@Mr.Wizard I thought Repeated will take care of a list with length 10. I saw your answer (stackoverflow.com/questions/8255210/…) before I posed my question. How can I use something like ListQ in this context of Repeated so that nfun[Range[10]] works. I am so dumb when it comes to use this fancy patterns :( – PlatoManiac Jun 20 '12 at 16:56
@PlatoManiac don't say you're dumb, this stuff gets complicated! In this case you need to think of Repeated as being a bare "sequence" of elements like 1, 2, 3 without a head, therefore you need { Repeated[ stuff ] } if you want to match a List with repeated elements inside it. This is similar to: f[ x__ ] := versus f[ {x__} ] := – Mr.Wizard Jun 20 '12 at 17:31

I'd have done nfun[M : {__Integer}] /; Length[M] == 10 := N@(Norm@(Sin[#] & /@ M)) myself, at least for your specific example.

-