All Downloads are FREE. Search and download functionalities are using the official Maven repository.

app.cash.quiver.extensions.Sequence.kt Maven / Gradle / Ivy

@file:Suppress("TYPEALIAS_EXPANSION_DEPRECATION", "DEPRECATION")

package app.cash.quiver.extensions

import arrow.core.Either
import arrow.core.None
import arrow.core.Option
import arrow.core.Some
import kotlin.experimental.ExperimentalTypeInference
import app.cash.quiver.extensions.traverse as quiverTraverse

/**
 * Map a function that returns an Either across the Sequence.
 */
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun  Sequence.traverse(f: (A) -> Either): Either> {
  // Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using
  //  Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid
  //  forcing too much of the sequence to be evaluated.
  val result = mutableListOf()
  forEach { a ->
    when (val mapped = f(a)) {
      is Either.Right -> result.add(mapped.value)
      is Either.Left -> return@traverse mapped
    }
  }
  return Either.Right(result.toList())
}

/**
 * Synonym for traverse((A)-> Either): Either>
 */
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun  Sequence.traverseEither(f: (A) -> Either): Either> =
  quiverTraverse(f)

/**
 * Map a function that returns an Option across the Sequence.
 */
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
inline fun  Sequence.traverse(f: (A) -> Option): Option> {
  // Note: Using a mutable list here avoids the stackoverflows one can accidentally create when using
  //  Sequence.plus instead. But we don't convert the sequence to a list beforehand to avoid
  //  forcing too much of the sequence to be evaluated.
  val result = mutableListOf()
  forEach { a ->
    when (val mapped = f(a)) {
      is Some -> result.add(mapped.value)
      is None -> return@traverse None
    }
  }
  return Some(result.toList())
}

/**
 * Synonym for traverse((A)-> Option): Option>
 */
@OptIn(ExperimentalTypeInference::class)
@OverloadResolutionByLambdaReturnType
@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
inline fun  Sequence.traverseOption(f: (A) -> Option): Option> =
  quiverTraverse(f)