15

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?

LCarvalho
  • 9,233
  • 4
  • 40
  • 96
Soldalma
  • 1,289
  • 1
  • 9
  • 17
  • 1
    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.) – march Sep 12 '16 at 18:31

4 Answers4

12

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.

Edmund
  • 42,267
  • 3
  • 51
  • 143
7

This tests if a symbol represents a Sequence:

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

or:

(mySeq -> 0)[[1, 0]] === Sequence
Coolwater
  • 20,257
  • 3
  • 35
  • 64
  • 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? – Soldalma Sep 14 '16 at 13:28
  • @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. – Coolwater Sep 14 '16 at 14:46
  • 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. – Soldalma Sep 14 '16 at 21:34
7
Internal`InheritedBlock[{FreeQ},
 SetAttributes[FreeQ, SequenceHold];
 FreeQ[mySeq, 1]
]
False
Kuba
  • 136,707
  • 13
  • 279
  • 740
6

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.

Jens
  • 97,245
  • 7
  • 213
  • 499