Hyperlinkv0.8.0-beta.28

Iterable

Iterable.scanconsteffect/Iterable.ts:399
<B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => Iterable<B>
<A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): Iterable<B>

Reduces an Iterable from the left, keeping all intermediate results instead of only the final result.

Example (Tracking running results)

import { Iterable } from "effect"

// Running sum of numbers
const numbers = [1, 2, 3, 4, 5]
const runningSum = Iterable.scan(numbers, 0, (acc, n) => acc + n)
console.log(Array.from(runningSum)) // [0, 1, 3, 6, 10, 15]

// Build strings progressively
const letters = ["a", "b", "c"]
const progressive = Iterable.scan(letters, "", (acc, letter) => acc + letter)
console.log(Array.from(progressive)) // ["", "a", "ab", "abc"]

// Track maximum values seen so far
const values = [3, 1, 4, 1, 5, 9, 2]
const runningMax = Iterable.scan(values, -Infinity, Math.max)
console.log(Array.from(runningMax)) // [-Infinity, 3, 3, 4, 4, 5, 9, 9]
folding
Source effect/Iterable.ts:39922 lines
export const scan: {
  <B, A>(b: B, f: (b: B, a: A) => B): (self: Iterable<A>) => Iterable<B>
  <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): Iterable<B>
} = dual(3, <A, B>(self: Iterable<A>, b: B, f: (b: B, a: A) => B): Iterable<B> => ({
  [Symbol.iterator]() {
    let acc = b
    let iterator: Iterator<A> | undefined
    function next() {
      if (iterator === undefined) {
        iterator = self[Symbol.iterator]()
        return { done: false, value: acc }
      }
      const result = iterator.next()
      if (result.done) {
        return result
      }
      acc = f(acc, result.value)
      return { done: false, value: acc }
    }
    return { next }
  }
}))