What is the pattern for an argument that must be a List of Integers

Given a function f defined as f[x_] := …
I understand that x_ can be anything.
If I want the argument x to be an Int, I would write f[x_Integer] := …
If I want the argument x to be a List, I would write f[x_List] := …
My question is now how would I specify that the argument x MUST BE a list of Ints so that I can call f like this f[{1,2,3}]

F[x:{(_Integer)…}] := x ?

f[ns : {___Integer}] = whatever (this includes an empty list)
f[ns : {__Integer}] = whatever (this excludes an empty list)

That works for a list of Integers. Thank you!
But how about an argument that could be a List of List of Integers as in calling F[{{1,2,3},{4,5,6}}] ?

You would need to do something like:

F[x_?(ArrayQ[#,1|2,IntegerQ])] :=

Look at pattern testing and ArrayQ

I will do that though I have read a lot about patterns.
In any case, something that would be great would be a repository of patterns. Some already exist in the documentation, but we would need more.
I know that with regular expressions there are dictionaries of patterns for things like:
valid credit card #'s
phone #'s
etc..
What would be nice would be able to give a pattern a name like
ListOfIntegers = {_ _ Integer}
then one could compose larger patterns as in
ListOfListOfIntegers = {
_ _ListOfIntegers } meaning a ListOfListOfIntegers is made up of a list of 1 or more ListsOfIntegers

What would be nice would be able to give a pattern a name…

You can certainly do this.

MyPattern = {_String, {__Integer}, _Symbol}

TheSymbols[structs : {MyPattern ...}] := structs[[All, -1]]

TheSymbols[{{"a", RandomInteger[10, 2], abc}, {"b", RandomInteger[10, 2], xyz}}]
(*returns {abc, xyz}*)

Never thought of that! Thank you!
So, is there some sort of repository of pattern expressions for commonly used patterns?
Things like patterns for URLs, IP addresses, street addresses, etc…?

Here’s a recursive pattern test that checks for lists of lists of…of lists of integers, that is, of arbitrarily nested lists of integers.

nestedListOfIntegerQ = MatchQ[#, {(_Integer | _?nestedListOfIntegerQ) ...}] &;

f[x_?nestedListOfIntegerQ] := Depth[x];

More examples of nested lists:

MatchQ[{1, 2, 3}, _?nestedListOfIntegerQ]
(*  True  *)

MatchQ[{{1, 2, 3}, {4, 5, 6}}, _?nestedListOfIntegerQ]
(*  True  *)

MatchQ[{{2}, {3, {4}, 5}}, _?nestedListOfIntegerQ]
(*  True  *)

(* Allows empty lists *)
MatchQ[{{}, {{}}}, _?nestedListOfIntegerQ]
(*  True  *)

Use double-dot .. (Repeated) instead of the triple-dot ... (RepeatedNull) to match nested lists, none of which are empty. If you want a mix, you’ll have to specify an explicit pattern for the specific mix.

Hello Michael,
Thank you very much. I will go and play with what you have taught me.

So, is there some sort of repository of pattern expressions for
commonly used patterns? Things like patterns for URLs, IP addresses,
street addresses, etc…?

Not patterns but Interpreter can do that.

I do not understand the Repeated patterns (“..” and “…”). Let me explain:

You can pick particular elements matching some conditions out of a list by Cases:

\text{Cases}[\{1,2.,3+i\},\text{e$\_$}\text{/;}e\in \mathbb{R}\land e>1]

==>
{2.}

If you Trace that you can see that Cases applies the conditions on each list element:

\text{Trace}[\text{Cases}[\{1,2.,3+i\},\text{e$\_$}\text{/;}e\in \mathbb{R}\land e>1]]

==> …

But I don’ t know how to match a list with such properties:

\text{MatchQ}[\{1,2.,3+i\},\{(\text{e$\_$}\text{/;}e\in \mathbb{R}\land e>1)\text{...}\}]

==>
False

… looks nice, but indeed this matches no list at all:

\text{MatchQ}[\{1.1,2.,3+1\},\{(\text{e$\_$}\text{/;}e\in \mathbb{R}\land e>1)\text{...}\}]

==>
False

If you Trace that you can see that MatchQ stops checking after the first list element and returns False in any case:

Hence I cannot define a function that accepts a list of real integers greater than 1.

\text{Block}[\{f\},f(\text{xs}:\{(\text{e$\_$}\text{/;}e\in \mathbb{R}\land e>1)\text{...}\})\text{:=}\text{xs}-1;f(\{1.1,2.,3+1\})]

==>
f[{1.1,2.,4}]

Note that “{(_)…}” is a correct pattern for any list:

\text{MatchQ}[\{1.1,2.,3+1\},\{(\_)\text{...}\}]

==>
True

Hi Werner,

Hence I cannot define a function that accepts a list of real integers
greater than 1.

How about this?

Block[{f},
 f[xs : {a : (_Real | _Integer) ..} /; AllTrue[{a}, # > 1 &]] := xs;
 Print[f[{2., 2, 3 + I}]];
 Print[f[{1., 1}]];
 Print[f[{.5, 2, 3 + 1}]];
 Print[f[{2., 2, 5/2}]];
 Print[f[{2., 1., 3 + 1}]];
 Print[f[{2., 2, 3 + 1}]];
 ]
(*
f[{2.,2,3+I}]
f[{1.,1}]
f[{0.5,2,4}]
f[{2.,2,5/2}]
f[{2.,1.,4}]
{2.,2,4}
*)

If you name the pattern, then all matches have to be the same expression:

MatchQ[{1.1, 2., 3 + 1}, {(e_ /; e ∈ Reals \[And] e > 1) ...}]
(*  False  : named, all three numbers are different *)

MatchQ[{2., 2., 2.}, {(e_ /; e ∈ Reals \[And] e > 1) ...}]
(*  True   : names, all are the Real 2. *)

MatchQ[{2., 2., 2}, {(e_ /; e ∈ Reals \[And] e > 1) ...}]
(*  False  : named, mix of Real 2. and Integer 2 -- not the same, even if equal *)

MatchQ[{2, 2, 2}, {(e_ /; e ∈ Reals \[And] e > 1) ...}]
(*  True   : named, all are the Integer 2 *)

MatchQ[{1.1, 2., 3 + 1}, {_?(# ∈ Reals \[And] # > 1 &) ...}]
(*  True   : unnamed pattern *)

The last with a PatternTest instead of a Condition is how to create the pattern with RepeatedNull.

Thanks, Rohit. Of course there many way to achieve my goal. I wanted to understand why I cannot do it with the simple condition:

f[xs:{(e_/;e∈ℝ&&e>1)...}]

Above Michael Rogers explained that I have to use (unnamed) PatternTest.

BTW: Your definition with “_Real | _Integer” would miss rationals, hence had to use

_Real | _Integer | _Rational

Great, Michael. I read that restriction “… same expression …”, but did not understand it. Now I learned why and how to use PatternTest.

Michael, just another question, concerning PatternTest for testing more than one variable.

As an example I want to match a list of 2D-vectors where y is greater than x. I can write:

MatchQ[{{1, 2}, {Pi, 3.2}}, {_?(#[[1]] < #[[2]] &) ...}]

==> True

But I cannot use a more readable form like:

MatchQ[{{1, 2}, {Pi, 3.2}}, {{_, _}?(#1 < #2 &) ...}]

==>

4313b.png

Do you know if there is something the like?

Hi Werner,

The ways I can think of immediately are three or four. Since PatternTest takes as an argument only the whole expression to be tested, if you want to test a relationship between its parts, then you have to get at the parts in some way.

Your first way, with Part, seems clear except for the mass of punctuation symbols. The [[]] can be replaced by words, First and Last. Since the length of # is 2, Last[#] gives the same result as #[[2]]. This might be appealing to some people:

MatchQ[{{1, 2}, {Pi, 3.2}}, {{_, _}?(#[[1]] < #[[2]] &) ...}]
(*True  *)

MatchQ[{{1, 2}, {Pi, 3.2}}, {{_, _}?(First[#] < Last[#] &) ...}]
(*True  *)

Here is a Less readable version (hope you don’t mind a pun):

MatchQ[{{1, 2}, {Pi, 3.2}}, {{_, _}?(Less @@ # &) ...}]
(*  True  *)

I hope the following is not confusing. The named patterns in {x_, y_} are a separate from the nameless pattern {_, _} being tested and repeated:

MatchQ[{{1, 2}, {Pi, 3.2}}, {{_, _}?(MatchQ[#, {x_, y_} /; x < y] &) ...}]
(*  True  *)

This last way is more verbose and probably a bit less efficient. Maybe it’s more readable. If so, then unless you are apply such patterns to large amounts of data, the efficiency is probably not as significant a concern as readability. Frankly, it’s took me years and years to get comfortable with patterns. As you learn more, what seems readable changes, too.

Anyway, these are the ideas I could come up with. Pick whichever one you find easiest to deal with.

Even though your question focused on RepeatedNull[], I maybe should have mentioned that

MatchQ[{1.1, 2., 3 + 1}, {_?(# ∈ Reals \[And] # > 1 &) ...}]

can also be done with ___ (BlankNullSequence[]) instead of ...:

MatchQ[{1.1, 2., 3 + 1}, {___?(# ∈ Reals \[And] # > 1 &)}]

Not pattern matching, but works :

In[1]:= And @@ Map[#[[1]] < #[[2]] &, {{1, 2}, {Pi, 3.2}}]
Out[1]= True

In[2]:= And @@ Map[#[[1]] < #[[2]] &, {{1, 2}, {4, 3.2}}]
Out[2]= False