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 maptype, the key type must betext(i. e.map<text, *>)
Virtual types operations
- Member access: Access elements using []for lists and maps,.namefor 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<*,*>,structor 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- Tfor simple types).
- in: Returns- trueif 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- trueif the given value is present in the virtual set; the type of the operand is- virtual<T>(or just- Tfor 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- nullif 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- Vis a simple type, returns- list<V>).
Special operators
- []: Get value by key, fails if not found, returns- virtual<V>(or just- Vfor simple types).
- in: Returns- trueif 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
    }
}