6
$\begingroup$

Is there any way to use the head of Integer and Real together like below? The below is not right, I know that, it is just for showing my thought.

f[x_(Integer||Real)] := x^2

The reason I ask this is because I need a function that receives an argument which is either integer or real.

$\endgroup$
6
  • 6
    $\begingroup$ x : (_Integer | _Real ). Look up Alternatives[]. $\endgroup$ Commented Jul 15, 2015 at 10:21
  • 6
    $\begingroup$ Integer and Real are data types. Are you sure this is what you want to check for? This is not the same as determining whether an arbitrary expression is integer or real (or rational or complex). Neither of Pi, Sqrt[2], 2/3 are either of Integer or Real type, but they are all real numbers. $\endgroup$
    – Szabolcs
    Commented Jul 15, 2015 at 10:22
  • 2
    $\begingroup$ You need Alternatives rather than Or. Either x : (_Integer | _Real) or x_Integer | x_Real will work. $\endgroup$
    – Mr.Wizard
    Commented Jul 15, 2015 at 10:22
  • 3
    $\begingroup$ Related to Szabolcs's note, you might want to just use NumberQ[]/NumericQ[] along with a test like x_ /; Im[x] == 0. $\endgroup$ Commented Jul 15, 2015 at 10:46
  • $\begingroup$ @Guess I was just getting around to that recommendation. :-) $\endgroup$
    – Mr.Wizard
    Commented Jul 15, 2015 at 10:47

2 Answers 2

11
$\begingroup$

To match your literal request you need Alternatives rather than Or.
Either x : (_Integer | _Real) or x_Integer | x_Real will work.

Following what Szabolcs and "Guess who it is" wrote you might define a realQ like so:

realQ = NumericQ[#] && Im[#] == 0 &;

f[x_?realQ] := x^2

f /@ {1, Pi, 1.3, 2/3, x^2, 7.1 - 2.8 I}
{1, π^2, 1.69, 4/9, f[x^2], f[7.1 - 2.8 I]}

Of note for those who are comfortable using undocumented functions:

Internal`RealValuedNumericQ /@ {1, Pi, 1.3, 2/3, x^2, 7.1 - 2.8 I}
{True, True, True, True, False, False}

There is also Internal`RealValuedNumberQ which passes only explicit numbers:

Internal`RealValuedNumberQ /@ {1, Pi, 1.3, 2/3, x^2, 7.1 - 2.8 I}
{True, False, True, True, False, False}
$\endgroup$
6
  • $\begingroup$ Thank you so much for the kind and elegant explanation! $\endgroup$ Commented Jul 15, 2015 at 13:46
  • $\begingroup$ @Smart You're welcome. :-) $\endgroup$
    – Mr.Wizard
    Commented Jul 15, 2015 at 13:56
  • $\begingroup$ Just a note: Internal`RealValuedNumberQ is consistent with the behavior of NumberQ which returns False when applied to Pi. $\endgroup$
    – rcollyer
    Commented Jul 15, 2015 at 14:41
  • $\begingroup$ @rcollyer I intended to imply that; sorry if I failed. $\endgroup$
    – Mr.Wizard
    Commented Jul 15, 2015 at 14:50
  • $\begingroup$ Just making it explicit. Implications are often lost. $\endgroup$
    – rcollyer
    Commented Jul 15, 2015 at 14:50
2
$\begingroup$

I frequently write functions that take one or more arguments which I limit to those quantities that mathematicians call real numbers. In Mathematica that means any quantity satisfying NumericQ excepting complex numbers. To facilitate writing such functions, I define a pattern

validNum = Except[_Complex, _?NumericQ];

This pattern is used like so:

f[x : validNum] := x^2

Update

As Guesswhoitis points out the above is not fool-proof. A more robust version is

validNum = Except[z_ /; Head[N[z]] === Complex, _?NumericQ];
f /@ {1, 1/2, .5, Pi, 1 + I/2, 1. + .5 I, Sqrt[-1], (-1)^(2/3), E + I Pi}
{1, 1/4, 0.25, Pi^2, f[1 + I/2], f[1. + 0.5*I], f[I], f[(-1)^(2/3)], f[E + I*Pi]}
$\endgroup$
8
  • $\begingroup$ How does it deal with E + I Pi or (-1)^(2/3)? $\endgroup$ Commented Jul 15, 2015 at 14:09
  • $\begingroup$ @Guesswhoitis. Not well, but I still find it useful. $\endgroup$
    – m_goldberg
    Commented Jul 15, 2015 at 14:15
  • 1
    $\begingroup$ @Mr.Wizard. You are right. I have fixed the error. I really must stop violating my own principle of "never post code you have not tested". $\endgroup$
    – m_goldberg
    Commented Jul 16, 2015 at 2:34
  • $\begingroup$ @Guesswhoitis. Do you find my update more to your liking? $\endgroup$
    – m_goldberg
    Commented Jul 16, 2015 at 2:36
  • $\begingroup$ I guess the only thing that would trip it up now would be 1. + 0. I and ilk, but it looks okay otherwise. $\endgroup$ Commented Jul 16, 2015 at 4:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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