Tuples and Vectors
Tuples
A tuple is a fixed-length, heterogeneous sequence of values.
Source: Primitive types
Syntax
export pure circuit tupleSyntax(hash: Bytes<32>): [Uint<64>, Boolean] {
// Tuple type: [T1, T2, ...]
const pair: [Uint<64>, Boolean] = [100, true];
const triple: [Field, Uint<8>, Bytes<32>] = [42, 255, hash];
return pair;
}
Tuple values are created with [e1, e2, ...] syntax.
Source: Tuple creation
The Unit Type []
The empty tuple [] is called the unit type. It’s commonly used as the return type for circuits that don’t return a value:
export circuit doSomething(): [] {
// perform operations
}
Source: Writing a contract
Tuple Element Access
Access tuple elements using bracket notation with a numeric literal:
export pure circuit access(): Uint<64> {
const pair: [Uint<64>, Boolean] = [100, true];
const first = pair[0]; // 100
const second = pair[1]; // true
return first;
}
Note: The index must be a numeric literal known at compile time.
Source: Element and member access expressions
Default Values
The default value of a tuple is a tuple where each element has its type’s default value:
[Uint<64>, Boolean]defaults to[0, false]
Source: Default values
Vectors
Vector<n, T> is a shorthand for a tuple of n elements all of type T. It’s exactly the same type as [T, T, ..., T] (n times).
Source: Primitive types
Syntax
export pure circuit vectors(): Vector<5, Uint<8>> {
// Vector<n, T> is shorthand for [T, T, ..., T]
const nums: Vector<5, Uint<8>> = [1, 2, 3, 4, 5];
const flags: Vector<3, Boolean> = [true, false, true];
// These are equivalent types:
// Vector<3, Field> === [Field, Field, Field]
return nums;
}
Vector Element Access
Same as tuples—use bracket notation with a numeric literal:
export pure circuit pick(): Uint<8> {
const nums: Vector<5, Uint<8>> = [1, 2, 3, 4, 5];
const third = nums[2]; // 3
return third;
}
Source: Element and member access expressions
Vectors and Tuples Subtyping
The relationship between vectors and tuples follows these rules:
- A tuple type
[T, ...]has a vector typeVector<n, S>when a least upper boundSexists for all element types - When a tuple has a vector type, the tuple is a subtype of that vector type
- A vector type
Vector<n, T>is a subtype of a tuple type[S, ...]of lengthnifTis a subtype of eachS
This means a vector can be passed where a compatible tuple is expected:
pure circuit processPair(p: [Uint<8>, Uint<8>]): Uint<16> {
return ((p[0] as Uint<16>) + (p[1] as Uint<16>)) as Uint<16>;
}
export circuit example(): Uint<16> {
const v: Vector<2, Uint<8>> = [10, 20];
return processPair(v); // Vector passed as tuple
}
Source: Subtyping and least upper bounds
TypeScript Representation
Both tuples and vectors are represented as TypeScript tuples or arrays:
// Compact: [Uint<64>, Boolean]
// TypeScript: [bigint, boolean]
// Compact: Vector<5, Uint<8>>
// TypeScript: bigint[]
Source: Representations in TypeScript
Exercises
Complete exercises/04_compound/01_tuples_vectors/.