<commit_before>/*jshint asi: true undef: true es5: true node: true browser: true devel: true
         forin: true latedef: false globalstrict: true */

'use strict';

var Method = require("method")
var end = require("./end")
var accumulated = require("./accumulated")

var accumulate = Method()

// Implementation of accumulate for the empty sequences.
function accumulateEmpty(_, f, start) { f(end(), start) }

// Both undefined and null are treated as empty collections,
// so the reduce accordingly.
accumulate.define(void(0), accumulateEmpty)
accumulate.define(null, accumulateEmpty)

// All other data structures that do not implement `accumulate`
// for their type are treated as sequences of single value.
accumulate.define(function(value, next, start) {
  next(end(), next(value, start))
})

// Unlike all other data built-in data structures in JS Arrays, do
// represent sequences, there for they implement `accumulate` differently.
accumulate.define(Array, function(array, next, initial) {
  var state = initial, index = 0, count = array.length
  while (index < count) {
    state = next(array[index++], state)
    if (state && state.is === accumulated) break
  }
  next(end(), state)
})

module.exports = accumulate
<commit_msg>Write docs for accumulate and add support for arguments.<commit_after>/*jshint asi: true undef: true es5: true node: true browser: true devel: true
         forin: true latedef: false globalstrict: true */

'use strict';

var Method = require("method")
var end = require("./end")
var accumulated = require("./accumulated")

var accumulate = Method()

// Implementation of accumulate for the empty sequences, that immediately
// signals end of sequence.
accumulate.empty = function accumulateEmpty(empty, next, start) {
  next(end(), start)
}
// Implementation of accumulate for the singular values which are treated
// as sequences with single element. Yields the given value and signals
// the end of sequence.
accumulate.singular = function accumulateSingular(value, next, start) {
  next(end(), next(value, start))
}
// Implementation accumulate for the array (and alike) values, such that it
// will call accumulator function `next` each time with next item and
// accumulated state until it's exhausted or `next` returns marked value
// indicating that it's done accumulating. Either way signals end to
// an accumulator.
accumulate.indexed = function accumulateIndexed(indexed, next, initial) {
  var state = initial, index = 0, count = indexed.length
  while (index < count) {
    state = next(indexed[index++], state)
    if (state && state.is === accumulated) break
  }
  next(end(), state)
}

// Both `undefined` and `null` implement accumulate for empty sequences.
accumulate.define(void(0), accumulate.empty)
accumulate.define(null, accumulate.empty)

// Array and arguments implement accumulate for indexed sequences.
accumulate.define(Array, accumulate.indexed)
accumulate.define((function() { return arguments })(), accumulate.indexed)

// All other built-in data structures are treated as single value sequences
// by default. Of course individual types may choose to override that.
accumulate.define(accumulate.singular)

module.exports = accumulate

{'fraction_non_alphanumeric': 0.10854647535870243, 'fraction_numerical': 0.0018714909544603868, 'mean_word_length': 4.510309278350515, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2168055', 'n_tokens_mistral': 902, 'n_tokens_neox': 843, 'n_words': 348}