A sequence
<a_0, a_2, ..., a_n>
is an ordered collection of elements that support several operations, inclduing fast random access.
Sequences support the following operations
-
lengthreturns the length of the sequence -
nthreturns the element at the specified position (counting from 0) -
emptyreturns an empty sequence -
singletontakes an element and returns a sequence that contains that element (only) -
tabulatetakes 1) a generator function that takes a position and generates the element at that position 2) a length and returns a sequence of the given length where the element at a given position is computed by appling the generator function (at that position) -
revreverses the given sequence -
appendtakes two sequences and appends them -
applytakes a function and a sequence, and applies the function to each element in the input sequence. -
applyitakes a function and a sequence, and applies the function to each position and the element at that position. It differs fromapplyin that it passes the element position as an argument to the function. -
maptakes a function from elements to (possibly new type of) elements and creates a new sequence by appling the function to each element -
subseqtakes a sequence and an interval and returns a subsequence that contains the elements in the given interval -
filtertakes a boolean function and a sequence and returns a new sequencue consisting of elements that satisfy the function -
flattentakes a sequence of sequences and flattens it into a single, flat sequencues by appending the nested sequencues, -
updatetakes an input sequence and a position value pair and returns a new sequence that is identical to the input sequence except at the given position, which contains the specified value. Theupdatefunction is pure is the sense that it does not modify the input sequence. -
injecttakes an input sequence and a sequencue of updates consisting of position-value pairs and returns a new sequence that is idential to the input sequence except and specified updates. For each updated position, the output sequence contains (an arbitrary) one of the updated values. Theinjectfunction is pure is the sense that it does not modify the input sequence. -
isEmptyreturnstrueif the input sequence is empty andfalseotherwise -
isSingletonreturnstrueif the input sequence is a singleton andfalseotherwise -
iteratetakes 1) an iterator function, 2) an initial value, 3) and a sequence and iteratively applies the iterator function to the elements of the sequence and previously computed value (or the initial value) and returns the final computed value -
reducetakes a 1) associative reducer function that maps to elements to another element, 2) the identity value of the reducer function, and 3) and a sequence and returs the reduced value for the sequence -
scantakes a 1) associative reducer function that maps to elements to another element, 2) the identity value of the reducer function, and 3) and a sequence and returns 1) the reduced value for each prefix of the sequence (starting with the emtpy sequence, for which the value is identity), and 2) the reduced value for the whole sequence
We can implement the sequence interface described above in a number of ways. For example, we can use weight-balanced trees to represent the elements in the sequence. Such an implementation has the advantage of allowing us to update an element of the sequence in logarithmic work but most other operations such as simple accesses also require logarithmic work. To provide for constant-work access we can use arrays. This comes at the cost of increasing the cost of updates to linear but this can be avoided in most cases, either by allowing for destructive updates or by using persistence (versioning).
We implement sequences by using arrays as the backing data structure. More specificially, we represent a sequence as an array slice, which is an array with a beginning and ending position.
-
Function
nthsimply accesses the element at the specified position in the underlying slice. -
Function
subseqreturns the specified subslice of the underlying slice. -
Function
tabulateallocates an array of sizenand populates it by using a parallel for that ranges over all positions in the array. -
Function
revreverses the given sequence by applying atabulate -
Function
appendtakes two sequences and appends them by usingtabulate -
Funciton
maptabulates a new sequence by using the provided map function on the input sequence. -
Functions
applyandapplyiaplies the given function for each position in the given array. The difference betweenapplyandapplyiis thatapplyipasses the position as argument to the update function. Both are implemented as a simple parallel-for loop over the sequence. -
Function
updatetakes an input sequence and a position value pair. It first creates a result sequence by copying the input sequence using amapand then updates the result sequence at the specified position with the given value. -
Function
injecttakes a sequence and an updat sequence consisting of index-value pairs, indicating the position and the value of the update respectively. It then creates a result array by first copying the input array and then applying each update in parallel. -
Function
reducecomputes a reduction over the sequence (with the given reducer function) by dividing the input sequence into two halves, recursively reducing each half, and computing the result by applying the reducer to the result from the two halves. -
Function
scanGencomputesreducefor all prefixes of the input sequence, including the empty and the full prefix. -
Functions
scanandiscansimply callscanGenand return the relevant subsequence of the full prefix reductions. -
Function
filterfirst computes an indicator sequence consisting of0and1entries that indicate whether the element at the corresponding position is to be excluded from the output or not (0means exclude,1means include). It then computes the offset for each included element by performing a scan, which also returns the total. Using the total, it allocates a result array and usesapplyito populate the result array by copying the included elements to their respective positions. -
Function
flattentakes a sequence of sequences and flattens it as a single "flat" sequence. To this end, it first computes a "length sequence" consisting of the length of each nested sequence by mappinglengthover the sequence. It then performs a scan over the length sequence to compute theoffsetsfor each nested sequence in the result flat sequence. Finally, it allocates the result array and copies each nested sequence by using a doubly nested loop over.