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

commonMain.arrow.optics.Every.kt Maven / Gradle / Ivy

There is a newer version: 2.0.1-alpha.1
Show newest version
package arrow.optics

import arrow.core.Either
import arrow.core.NonEmptyList
import arrow.core.Option
import arrow.core.Tuple10
import arrow.core.Tuple4
import arrow.core.Tuple5
import arrow.core.Tuple6
import arrow.core.Tuple7
import arrow.core.Tuple8
import arrow.core.Tuple9
import arrow.core.fold
import arrow.core.foldMap
import arrow.typeclasses.Monoid
import kotlin.jvm.JvmStatic

public typealias Every = PEvery

/**
 * Composition of Fold and Traversal
 * It combines their powers
 */
public interface PEvery : PTraversal, Fold, PSetter {

  /**
   * Map each target to a type R and use a Monoid to fold the results
   */
  override fun  foldMap(M: Monoid, source: S, map: (focus: A) -> R): R

  override fun modify(source: S, map: (focus: A) -> B): T

  /**
   * Compose a [PEvery] with a [PEvery]
   */
  public infix fun  compose(other: PEvery): PEvery =
    object : PEvery {
      override fun  foldMap(M: Monoid, source: S, map: (C) -> R): R =
        [email protected](M, source) { c -> other.foldMap(M, c, map) }

      override fun modify(source: S, map: (focus: C) -> D): T =
        [email protected](source) { b -> other.modify(b, map) }
    }

  public operator fun  plus(other: PEvery): PEvery =
    this compose other

  public companion object {
    public fun  from(T: Traversal, F: Fold): Every =
      object : Every {
        override fun  foldMap(M: Monoid, source: S, map: (A) -> R): R = F.foldMap(M, source, map)
        override fun modify(source: S, map: (focus: A) -> A): S = T.modify(source, map)
      }

    /**
     * [Traversal] for [List] that focuses in each [A] of the source [List].
     */
    @JvmStatic
    public fun  list(): Every, A> =
      object : Every, A> {
        override fun modify(source: List, map: (focus: A) -> A): List =
          source.map(map)

        override fun  foldMap(M: Monoid, source: List, map: (focus: A) -> R): R =
          source.foldMap(M, map)
      }

    /**
     * [Traversal] for [Either] that has focus in each [Either.Right].
     *
     * @return [Traversal] with source [Either] and focus every [Either.Right] of the source.
     */
    @JvmStatic
    public fun  either(): Every, R> =
      object : Every, R> {
        override fun modify(source: Either, map: (focus: R) -> R): Either =
          source.map(map)

        override fun  foldMap(M: Monoid, source: Either, map: (focus: R) -> A): A =
          source.fold({ M.empty() }, map)
      }

    @JvmStatic
    public fun  map(): Every, V> =
      object : Every, V> {
        override fun modify(source: Map, map: (focus: V) -> V): Map =
          source.mapValues { (_, v) -> map(v) }

        override fun  foldMap(M: Monoid, source: Map, map: (focus: V) -> R): R = M.run {
          source.fold(empty()) { acc, (_, v) -> acc.combine(map(v)) }
        }
      }

    /**
     * [Traversal] for [NonEmptyList] that has focus in each [A].
     *
     * @receiver [PTraversal.Companion] to make it statically available.
     * @return [Traversal] with source [NonEmptyList] and focus every [A] of the source.
     */
    @JvmStatic
    public fun  nonEmptyList(): Every, A> =
      object : Every, A> {
        override fun modify(source: NonEmptyList, map: (focus: A) -> A): NonEmptyList =
          source.map(map)

        override fun  foldMap(M: Monoid, source: NonEmptyList, map: (focus: A) -> R): R =
          source.foldMap(M, map)
      }

    /**
     * [Traversal] for [Option] that has focus in each [arrow.core.Some].
     *
     * @receiver [PTraversal.Companion] to make it statically available.
     * @return [Traversal] with source [Option] and focus in every [arrow.core.Some] of the source.
     */
    @JvmStatic
    public fun  option(): Every, A> =
      object : Every, A> {
        override fun modify(source: Option, map: (focus: A) -> A): Option =
          source.map(map)

        override fun  foldMap(M: Monoid, source: Option, map: (focus: A) -> R): R =
          source.fold({ M.empty() }, map)
      }

    @JvmStatic
    public fun  sequence(): Every, A> =
      object : Every, A> {
        override fun modify(source: Sequence, map: (focus: A) -> A): Sequence =
          source.map(map)

        override fun  foldMap(M: Monoid, source: Sequence, map: (focus: A) -> R): R =
          source.foldMap(M, map)
      }

    /**
     * [Traversal] for [String] that focuses in each [Char] of the source [String].
     *
     * @receiver [PTraversal.Companion] to make it statically available.
     * @return [Traversal] with source [String] and foci every [Char] in the source.
     */
    @JvmStatic
    public fun string(): Every =
      object : Every {
        override fun modify(source: String, map: (focus: Char) -> Char): String =
          source.map(map).joinToString(separator = "")

        override fun  foldMap(M: Monoid, source: String, map: (focus: Char) -> R): R = M.run {
          source.fold(empty()) { acc, char -> acc.combine(map(char)) }
        }
      }

    /**
     * [Traversal] to focus into the first and second value of a [Pair]
     */
    @JvmStatic
    public fun  pair(): Every, A> =
      object : Every, A> {
        override fun modify(source: Pair, map: (focus: A) -> A): Pair =
          Pair(map(source.first), map(source.second))

        override fun  foldMap(M: Monoid, source: Pair, map: (focus: A) -> R): R =
          listOf(source.first, source.second)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second and third value of a [Triple]
     */
    @JvmStatic
    public fun  triple(): Every, A> =
      object : Every, A> {
        override fun modify(source: Triple, map: (focus: A) -> A): Triple =
          Triple(map(source.first), map(source.second), map(source.third))

        override fun  foldMap(M: Monoid, source: Triple, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third and fourth value of a [arrow.core.Tuple4]
     */
    @JvmStatic
    public fun  tuple4(): Every, A> =
      object : Every, A> {
        override fun modify(source: Tuple4, map: (focus: A) -> A): Tuple4 =
          Tuple4(map(source.first), map(source.second), map(source.third), map(source.fourth))

        override fun  foldMap(M: Monoid, source: Tuple4, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth)
            .foldMap(M, map)
      }

    /**
     * [PTraversal] to focus into the first, second, third, fourth and fifth value of a [arrow.core.Tuple5]
     */
    @JvmStatic
    public fun  tuple5(): Every, A> =
      object : Every, A> {
        override fun modify(source: Tuple5, map: (focus: A) -> A): Tuple5 =
          Tuple5(map(source.first), map(source.second), map(source.third), map(source.fourth), map(source.fifth))

        override fun  foldMap(M: Monoid, source: Tuple5, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third, fourth, fifth and sixth value of a [arrow.core.Tuple6]
     */
    @JvmStatic
    public fun  tuple6(): Every, A> =
      object : Every, A> {
        override fun modify(source: Tuple6, map: (focus: A) -> A): Tuple6 =
          Tuple6(
            map(source.first),
            map(source.second),
            map(source.third),
            map(source.fourth),
            map(source.fifth),
            map(source.sixth)
          )

        override fun  foldMap(M: Monoid, source: Tuple6, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third, fourth, fifth, sixth and seventh value of a [arrow.core.Tuple7]
     */
    @JvmStatic
    public fun  tuple7(): Every, A> =
      object : Every, A> {
        override fun modify(source: Tuple7, map: (focus: A) -> A): Tuple7 =
          Tuple7(
            map(source.first),
            map(source.second),
            map(source.third),
            map(source.fourth),
            map(source.fifth),
            map(source.sixth),
            map(source.seventh)
          )

        override fun  foldMap(M: Monoid, source: Tuple7, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third, fourth, fifth, sixth, seventh and eight value of a [arrow.core.Tuple8]
     */
    @JvmStatic
    public fun  tuple8(): Every, A> =
      object : Every, A> {
        override fun modify(
          source: Tuple8,
          map: (focus: A) -> A
        ): Tuple8 =
          Tuple8(
            map(source.first),
            map(source.second),
            map(source.third),
            map(source.fourth),
            map(source.fifth),
            map(source.sixth),
            map(source.seventh),
            map(source.eighth)
          )

        override fun  foldMap(M: Monoid, source: Tuple8, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third, fourth, fifth, sixth, seventh, eight and ninth value of a [arrow.core.Tuple9]
     */
    @JvmStatic
    public fun  tuple9(): Every, A> =
      object : Every, A> {
        override fun modify(
          source: Tuple9,
          map: (focus: A) -> A
        ): Tuple9 =
          Tuple9(
            map(source.first),
            map(source.second),
            map(source.third),
            map(source.fourth),
            map(source.fifth),
            map(source.sixth),
            map(source.seventh),
            map(source.eighth),
            map(source.ninth)
          )

        override fun  foldMap(M: Monoid, source: Tuple9, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth)
            .foldMap(M, map)
      }

    /**
     * [Traversal] to focus into the first, second, third, fourth, fifth, sixth, seventh, eight, ninth and tenth value of a [arrow.core.Tuple10]
     */
    @JvmStatic
    public fun  tuple10(): Every, A> =
      object : Every, A> {
        override fun modify(
          source: Tuple10,
          map: (focus: A) -> A
        ): Tuple10 =
          Tuple10(
            map(source.first),
            map(source.second),
            map(source.third),
            map(source.fourth),
            map(source.fifth),
            map(source.sixth),
            map(source.seventh),
            map(source.eighth),
            map(source.ninth),
            map(source.tenth)
          )

        override fun  foldMap(M: Monoid, source: Tuple10, map: (focus: A) -> R): R =
          listOf(source.first, source.second, source.third, source.fourth, source.fifth, source.sixth, source.seventh, source.eighth, source.ninth, source.tenth)
            .foldMap(M, map)
      }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy