Hyperlinkv0.8.0-beta.28

Stream

Stream.changesWithconsteffect/Stream.ts:9256
<A>(f: (x: A, y: A) => boolean): <E, R>(
  self: Stream<A, E, R>
) => Stream<A, E, R>
<A, E, R>(self: Stream<A, E, R>, f: (x: A, y: A) => boolean): Stream<
  A,
  E,
  R
>

Returns a stream that only emits elements that are not equal to the previously emitted element, as determined by the specified predicate.

Example (Emitting values that changed by equivalence)

import { Console, Effect, Stream } from "effect"

const stream = Stream.make("A", "a", "B", "b", "b").pipe(
  Stream.changesWith((left, right) => left.toLowerCase() === right.toLowerCase())
)

Effect.runPromise(
  Effect.gen(function*() {
    const values = yield* Stream.runCollect(stream)
    yield* Console.log(values)
  })
)
// ["A", "B"]
Deduplication
Source effect/Stream.ts:925629 lines
export const changesWith: {
  <A>(f: (x: A, y: A) => boolean): <E, R>(self: Stream<A, E, R>) => Stream<A, E, R>
  <A, E, R>(self: Stream<A, E, R>, f: (x: A, y: A) => boolean): Stream<A, E, R>
} = dual(
  2,
  <A, E, R>(self: Stream<A, E, R>, f: (x: A, y: A) => boolean): Stream<A, E, R> =>
    transformPull(self, (pull, _scope) =>
      Effect.sync(() => {
        let first = true
        let last: A
        return Effect.flatMap(pull, function loop(arr): Pull.Pull<Arr.NonEmptyReadonlyArray<A>, E> {
          const out: Array<A> = []
          let i = 0
          if (first) {
            first = false
            last = arr[0]
            i = 1
            out.push(last)
          }
          for (; i < arr.length; i++) {
            const a = arr[i]
            if (f(a, last)) continue
            last = a
            out.push(a)
          }
          return Arr.isArrayNonEmpty(out) ? Effect.succeed(out) : Effect.flatMap(pull, loop)
        })
      }))
)
Referenced by 1 symbols