4
$\begingroup$

I am defining a pattern to be used as a test, that itself depends on an argument. For instance, I might want to check that something appears in a given list:

type[x_] := (MemberQ[x, #] &);

I naively used this in the definition of a function and do not get what I expected. Defining

Z2 = {0, 1};
f[x_?type[Z2]] := x

returns f[0] when evaluating f[0]. Putting brackets

g[x_?(type[Z2])] := x

gives the desired 0 when evaluating g[0].

I understand the need for brackets here, as one might want to pattern test an object and then supply it an argument -- (f_?test)[x] -- and I do not mean to get into a discussion about the choice made by Mathematica here.

My question is whether there is a way to define the pattern test "type", so as to avoid the need for subsequent brackets.

$\endgroup$
6
  • $\begingroup$ Question unclear to me. Could you please add an example of what are your starting data and of what you want to get? $\endgroup$
    – vi pa
    Commented Feb 27, 2020 at 0:45
  • $\begingroup$ In terms of "starting data", everything is defined in the question. What I am hoping to get is a definition of the function "type", so that the definition f[x_?type[Z2]]:=x evaluates f[0] to 0, not to f[0], doing so without using extra brackets as used in the function g. $\endgroup$
    – Stijn
    Commented Mar 1, 2020 at 13:52
  • $\begingroup$ This is an attemp of solution: type[x_,y_]:=MemberQ[x,y] and then f[x/;type[Z2,x]]:=x. $\endgroup$
    – vi pa
    Commented Mar 2, 2020 at 13:52
  • $\begingroup$ Thanks for the suggestion! Your way gives the correct outcome as well, but requires explicitly specifying the argument of the function, so is not quite what I was hoping for. (Put differently, your workaround involves at least as much typing as adding the extra brackets that were needed in my definition.) In any case, thanks again for looking at this! $\endgroup$
    – Stijn
    Commented Mar 5, 2020 at 16:22
  • $\begingroup$ fwiw, you can do t=type[Z2]; f[x_?t] := x $\endgroup$
    – kglr
    Commented Apr 9, 2020 at 10:39

1 Answer 1

5
$\begingroup$

We can TagSet or UpSet a definition upon type to elevate a PatternTest expression with the second argument being type into a pure function that can accept arguments. We use Vertabim to address PatternTest literally.

Verbatim[PatternTest][body_, type] ^:= body?(type[##]) &;

h[x_?type[Z2]] := x

h[0]
0
$\endgroup$
3
  • 6
    $\begingroup$ welcome back! Very nice: always learn something +1 :) $\endgroup$
    – ubpdqn
    Commented Jan 2 at 17:46
  • 2
    $\begingroup$ @ubpdqn Thanks! I thought I should let people know I'm still alive. :^) $\endgroup$
    – Mr.Wizard
    Commented Jan 2 at 18:09
  • 4
    $\begingroup$ @Mr.Wizard MSE became a poorer site without your activity. I hope you are going stay here for longer. $\endgroup$
    – Artes
    Commented Jan 4 at 0:39

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.