-
Notifications
You must be signed in to change notification settings - Fork 4
2018 002 Additional slice operations
Author: John Reppy
Last revised: September 2, 2018
Status: proposed
Discussion: issue #25
This proposal adds operations to the vector and array slice strutures.
signature MONO_VECTOR_SLICE =
sig
...
val triml : int -> slice -> slice
val trimr : int -> slice -> slice
val splitAt : slice * int -> slice * slice
val getVec : slice * int -> (vector * slice) option
end
signature MONO_ARRAY_SLICE =
sig
...
val triml : int -> slice -> slice
val trimr : int -> slice -> slice
val splitAt : slice * int -> slice * slice
val getVec : slice * int -> (vector * slice) option
end
signature VECTOR_SLICE =
sig
...
val triml : int -> 'a slice -> 'a slice
val trimr : int -> 'a slice -> 'a slice
val splitAt : 'a slice * int -> 'a slice * 'a slice
val getVec : 'a slice * int -> ('a vector * 'a slice) option
end
signature ARRAY_SLICE =
sig
...
val triml : int -> 'a slice -> 'a slice
val trimr : int -> 'a slice -> 'a slice
val splitAt : 'a slice * int -> 'a slice * 'a slice
val getVec : 'a slice * int -> ('a vector * 'a slice) option
end
The semantics of these operations is independent of the underlying slice and vector types, so we give a generic description.
triml n slice
removes `n` elements from the left end of the slice `s`. If `n` is greater than the number of elements in the slice, then the empty slice is returned.
trimr n slice
removes `n` elements from the right end of the slice `s`. If `n` is greater than the number of elements in the slice, then the empty slice is returned.
splitAt (slice, i)
returns the pair of slices `(slice1, slice2)`, where `slice1` contains the first `i` elements of `slice1` and `slice2` contains the rest of the elements. If `i` is negative or greater than the number of elements in the slice, then `Subscript` is raised. The underlying vector (or array) of `slice`, `slice1`, and `slice2` will be the same.
getVec (slice, n)
returns `SOME(v, rest)`, where `v` is a vector of the first `n` elements of `slice` and `rest` is the slice containing the remaining elements, assuming that `slice` has at least `n` elements. Otherwise, `NONE` is returned.
These additional operations make manipulation of slices more convenient. They can be directly defined in terms of existing operations as follows:
fun triml n s = if (n < length s)
then subslice(s, n, NONE)
else subslice(s, length s, NONE)
fun trimr n s = if (n < length s)
then subslice(s, 0, SOME(length s - n))
else subslice(s, 0, SOME 0)
fun splitAt (s, i) = (subslice(s, 0, SOME i), subslice(s, i, NONE))
fun getVec (s, n) = if (n < length s)
then let
val (s1, s2) = splitAt (s, n)
in
SOME(vector s1, s2)
end
else NONE
This propsal adds new variables to existing basis modules. Most code should be unaffected, but there are a few uncommon situations where existing code will break. These situations include
-
code that opens an extended structure in a context where the new identifiers are already bound.
-
code that includes an extended signature in a context where the new identifiers are already bound.
-
structures that match the old signature, but do not include an implementation of the new operations.
Currently, the processing of slices in a chunk-wise fashion is difficult; addition
of these operations would make it more convenient (and slightly more efficient).
The first three of these operations already exist in the Substring
structure and the getVec
operation is a natural generalization of getElem
,
so these operations are a natural extension to the slice structures.
- [2018-09-02] Original proposal.