Skip to main content

Virtual types

Virtual types use Merkle trees to efficiently verify data integrity and selectively retrieve specific elements.

Type virtual<T> supports the following types of T:

  • list<*>
  • set<*>
  • map<text, *>

T elements constraints

Additionally, types of all internal elements of T must satisfy the following constraints:

  • must be Gtv-compatible
  • for a map type, the key type must be text (i. e. map<text, *>)

Virtual types operations

  • Member access: Access elements using [] for lists and maps, .name for structs and tuples.
  • .to_full(): T: Converts a virtual value to its full, original form if all elements are present; otherwise throws an exception.

Features of virtual<T>

  • Virtual values cannot be modified after creation.
  • Member access returns virtual values of the corresponding type, maintaining partial representation. Reading a member of type list<*>, map<*,*>, struct or tuple returns a value of the corresponding virtual type, not of the actual member type.
  • Cannot get converted to Gtv, so can't use it as a return type of a query.
Example
struct Record {
t: text;
s: integer;
}

operation processRecords(virtualRecords: virtual<list<Record>>) {
for (virtualRecord in virtualRecords) { // "virtualRecord" is of type "virtual<Record>"
val fullRecord = virtualRecord.to_full(); // "fullRecord" is of type "Record", fails if the value is not full
print(fullRecord.t); // Print the 't' field of the fully retrieved Record
}
}

Virtual<list<T>> functions

  • .empty(): boolean: Checks if the virtual value is empty.

  • .get(integer): virtual<T>: Retrieves an element by index (same as []).

  • .join_to_text(): text: Creates a text from all elements using the specified separator, prefix, and postfix.

  • .size(): integer: Returns the number of elements.

  • .to_full(): list<T>: Converts to the original list, fails if the value isn't full.

  • .to_text(): text: Returns a text representation.

Special operators

  • []: Element read, returns virtual<T> (or just T for simple types).
  • in: Returns true if the given integer index is present in the virtual list.
Example
operation listExample(virtualList: virtual<list<integer>>) {
print(virtualList.empty()); // Check if the list is empty
print(virtualList.size()); // Print the size of the list
print(virtualList[0]); // Access and print the first element

for (i in virtualList) {
print(virtualList[i]); // Iterate and print all elements
}
}

Virtual<set<T>> functions

  • .empty(): boolean: Checks if the virtual set is empty.
  • .join_to_text(): text: Creates a text from all elements using the specified separator, prefix, and postfix.
  • .size(): integer: Returns the number of elements.
  • .to_full(): set<T>: Converts to the original set, fails if the value isn't full.
  • .to_text(): text: Returns a text representation.

Special operators

  • in: Returns true if the given value is present in the virtual set; the type of the operand is virtual<T> (or just T for simple types).
Example
operation setExample(virtualSet: virtual<set<text>>) {
print(virtualSet.empty()); // Check if the set is empty
print(virtualSet.size()); // Print the size of the set

if ("example" in virtualSet) { // Check if an element is in the set
print("Element 'example' is in the set");
}

for (element in virtualSet.to_full()) {
print(element); // Iterate and print all elements
}
}

Virtual<map<text, T>> functions

  • .contains(K): boolean: Checks if a key is in the map (same as the operator in).
  • .empty(): boolean: Checks if the virtual mal is empty.
  • .get(K): virtual<V>: Gets the value associated with a key in the map. Fails if the key is not found.
  • .get_or_default (key: K, default: R): R: Gets the value associated with a key in the map, or a default value if the key is not found.
  • .get_or_null(key: K): V?: Gets the value associated with a key in the map, returning null if the key is not found.
  • .join_to_text(): text: Creates a text from all elements using the specified separator, prefix, and postfix.
  • .keys(): set<K>: Returns a copy of keys.
  • .size(): integer: Returns the number of elements.
  • .to_full(): map<K, V>: Converts to the original map, fails if the value isn't full.
  • .to_text(): text: Converts the map to text.
  • .values(): list<virtual<V>>: Returns a copy of values (if V is a simple type, returns list<V>).

Special operators

  • []: Get value by key, fails if not found, returns virtual<V> (or just V for simple types).
  • in: Returns true if a key is in the map.
Example
operation mapExample(virtualMap: virtual<map<text, integer>>) {
print(virtualMap.empty()); // Check if the map is empty
print(virtualMap.size()); // Print the size of the map

if ("key" in virtualMap) { // Check if a key is in the map
print(virtualMap["key"]); // Access and print the value associated with the key
}

for (k in virtualMap.keys()) {
print(k); // Iterate and print all keys
}

for (value in virtualMap.values()) {
print(value); // Iterate and print all values
}
}