15
$\begingroup$

I created a variable that represents a sequence:

mySeq = Sequence[1, 2, 3];

I wanted to use that variable as an argument for some functions. But I got in trouble. For example,

FreeQ[mySeq, 1]

generates an error message.

So I wanted to test if mySeq was a sequence before I used it as an argument. But there is no predicate SequenceQ and

Head[mySeq]

also generates an error message.

Is there a way to test whether mySeq is a sequence object?

$\endgroup$
  • 1
    $\begingroup$ It's possible that this is an XY problem (although it's an interesting question in it's own right). Can you instead define mySeq as a List and use Apply? For instance, if mySeq = {1,2,3}, then f @@ mySeq evaluates to f[1, 2, 3]. (@@ is the infix form of Apply.) $\endgroup$ – march Sep 12 '16 at 18:31
12
$\begingroup$

You may make a helper function with attribute SequenceHold.

ClearAll[sequenceQ];
Attributes[sequenceQ] = {SequenceHold};
sequenceQ[_Sequence] = True;
sequenceQ[_] = False;

This can be used to test for a sequence directly or with mapping and threading functions as can the built in *Q functions. Note that I use Set here instead of SetDelayed as it works better for this particular function definition.

mySeq = Sequence[1, 2, 3];
sequenceQ[mySeq]

(* True *)

Hope this helps.

$\endgroup$
  • $\begingroup$ Changed from SetDelayed to Set has it works better with this function. $\endgroup$ – Edmund Sep 12 '16 at 18:41
7
$\begingroup$
Internal`InheritedBlock[{FreeQ},
 SetAttributes[FreeQ, SequenceHold];
 FreeQ[mySeq, 1]
]
False
$\endgroup$
7
$\begingroup$

This tests if a symbol represents a Sequence:

With[{a = mySeq}, HoldComplete[a][[1, 0]]] === Sequence

or:

(mySeq -> 0)[[1, 0]] === Sequence
$\endgroup$
  • $\begingroup$ Great! But could you explain why HoldComplete[mySeq] and HoldComplete[a] in your solution have different results? The With[] scoping made the difference, but why? $\endgroup$ – Soldalma Sep 14 '16 at 13:28
  • $\begingroup$ @FernandoSaldanha Nothing happens inside HoldComplete. Hence it is needed for mySeq to be evaluated once before it is put into HoldComplete. Otherwise the result would be HoldComplete[myseq]. The first place where mySeq is evaluated must have attribute SequenceHold like Set which I've used. The trick can be done with Rule that also has SequenceHold. $\endgroup$ – Coolwater Sep 14 '16 at 14:46
  • $\begingroup$ Ok, thanks. But why do you need the call to Set to be within the first argument of With[] ? Without this the assignment to a would not help. $\endgroup$ – Soldalma Sep 14 '16 at 21:34
6
$\begingroup$

How about this, which doesn't require any tests:

mySeq = Sequence[1, 2, 3];
seqFreeQ[s__, x_] := FreeQ[Flatten[{s}], x]
seqFreeQ[mySeq, 1]
(* ==> False *)

The first argument of the function allows a sequence, which is then wrapped in a List to apply FreeQ. The Flatten is optional.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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