Skip to content

Commit

Permalink
Merge pull request #10624 from shardulc/2.13.x
Browse files Browse the repository at this point in the history
Specify behavior of folds and reduces when operator is not associative or collection is unordered
  • Loading branch information
SethTisue committed Jan 30, 2024
2 parents d9c839c + ef2428c commit f973d13
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 153 deletions.
75 changes: 38 additions & 37 deletions src/library/scala/collection/ArrayOps.scala
Expand Up @@ -761,20 +761,19 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
true
}

/** Applies a binary operator to a start value and all elements of this array,
* going left to right.
*
* @param z the start value.
* @param op the binary operator.
* @tparam B the result type of the binary operator.
* @return the result of inserting `op` between consecutive elements of this array,
* going left to right with the start value `z` on the left:
* {{{
* op(...op(z, x_1), x_2, ..., x_n)
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this array.
* Returns `z` if this array is empty.
*/
/** Applies the given binary operator `op` to the given initial value `z` and
* all elements of this array, going left to right. Returns the initial value
* if this array is empty.
*
* If `x,,1,,`, `x,,2,,`, ..., `x,,n,,` are the elements of this array, the
* result is `op( op( ... op( op(z, x,,1,,), x,,2,,) ... ), x,,n,,)`.
*
* @param z An initial value.
* @param op A binary operator.
* @tparam B The result type of the binary operator.
* @return The result of applying `op` to `z` and all elements of this array,
* going left to right. Returns `z` if this array is empty.
*/
def foldLeft[B](z: B)(op: (B, A) => B): B = {
def f[@specialized(Specializable.Everything) T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
val length = xs.length
Expand Down Expand Up @@ -867,20 +866,20 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {
res
}

/** Applies a binary operator to all elements of this array and a start value,
* going right to left.
*
* @param z the start value.
* @param op the binary operator.
* @tparam B the result type of the binary operator.
* @return the result of inserting `op` between consecutive elements of this array,
* going right to left with the start value `z` on the right:
* {{{
* op(x_1, op(x_2, ... op(x_n, z)...))
* }}}
* where `x,,1,,, ..., x,,n,,` are the elements of this array.
* Returns `z` if this array is empty.
*/
/** Applies the given binary operator `op` to all elements of this array and
* the given initial value `z`, going right to left. Returns the initial
* value if this array is empty.
*
* If `x,,1,,`, `x,,2,,`, ..., `x,,n,,` are the elements of this array, the
* result is `op(x,,1,,, op(x,,2,,, op( ... op(x,,n,,, z) ... )))`.
*
* @param z An initial value.
* @param op A binary operator.
* @tparam B The result type of the binary operator.
* @return The result of applying `op` to all elements of this array
* and `z`, going right to left. Returns `z` if this array
* is empty.
*/
def foldRight[B](z: B)(op: (A, B) => B): B = {
def f[@specialized(Specializable.Everything) T](xs: Array[T], op: (Any, Any) => Any, z: Any): Any = {
var v = z
Expand All @@ -907,15 +906,17 @@ final class ArrayOps[A](private val xs: Array[A]) extends AnyVal {

}

/** Folds the elements of this array using the specified associative binary operator.
*
* @tparam A1 a type parameter for the binary operator, a supertype of `A`.
* @param z a neutral element for the fold operation; may be added to the result
* an arbitrary number of times, and must not change the result (e.g., `Nil` for list concatenation,
* 0 for addition, or 1 for multiplication).
* @param op a binary operator that must be associative.
* @return the result of applying the fold operator `op` between all the elements, or `z` if this array is empty.
*/
/** Alias for [[foldLeft]].
*
* The type parameter is more restrictive than for `foldLeft` to be
* consistent with [[IterableOnceOps.fold]].
*
* @tparam A1 The type parameter for the binary operator, a supertype of `A`.
* @param z An initial value.
* @param op A binary operator.
* @return The result of applying `op` to `z` and all elements of this array,
* going left to right. Returns `z` if this string is empty.
*/
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1 = foldLeft(z)(op)

/** Builds a new array by applying a function to all elements of this array.
Expand Down

0 comments on commit f973d13

Please sign in to comment.