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

kyo.Env.scala Maven / Gradle / Ivy

The newest version!
package kyo

import kyo.*
import kyo.Tag
import kyo.kernel.*
import scala.util.NotGiven

/** Represents an environment effect that provides access to typed values.
  *
  * @tparam R
  *   The type of values in the environment
  */
sealed trait Env[+R] extends ContextEffect[TypeMap[R]]

/** Companion object for Env, providing utility methods for working with environments. */
object Env:

    given eliminateEnv: Reducible.Eliminable[Env[Any]] with {}
    private inline def erasedTag[R] = Tag[Env[Any]].asInstanceOf[Tag[Env[R]]]

    /** Retrieves a value of type R from the environment.
      *
      * @tparam R
      *   The type of value to retrieve
      * @return
      *   A computation that retrieves the value from the environment
      */
    inline def get[R](using inline tag: Tag[R])(using inline frame: Frame): R < Env[R] =
        use[R](identity)

    /** Runs a computation with a provided environment value.
      *
      * @param env
      *   The environment value
      * @param v
      *   The computation to run
      * @return
      *   The result of the computation with the environment handled
      */
    def run[R >: Nothing: Tag, A: Flat, S, VR](env: R)(v: A < (Env[R & VR] & S))(
        using
        reduce: Reducible[Env[VR]],
        frame: Frame
    ): A < (S & reduce.SReduced) =
        runTypeMap(TypeMap(env))(v)

    /** Runs a computation with a provided TypeMap environment.
      *
      * @param env
      *   The TypeMap environment
      * @param v
      *   The computation to run
      * @return
      *   The result of the computation with the environment handled
      */
    def runTypeMap[R >: Nothing, A: Flat, S, VR](env: TypeMap[R])(v: A < (Env[R & VR] & S))(
        using
        reduce: Reducible[Env[VR]],
        frame: Frame
    ): A < (S & reduce.SReduced) =
        reduce(ContextEffect.handle(erasedTag[R], env, _.union(env))(v): A < (Env[VR] & S))

    /** Runs a computation with an environment created from provided layers.
      *
      * @param layers
      *   The layers to create the environment from
      * @param value
      *   The computation to run
      * @return
      *   The result of the computation with the layered environment handled
      */
    transparent inline def runLayer[A, S, V](inline layers: Layer[?, ?]*)(value: A < (Env[V] & S)): A < Nothing =
        inline Layer.init[V](layers*) match
            case layer: Layer[V, s] =>
                layer.run.map { env =>
                    runTypeMap(env)(value)
                }

    /** Provides operations for using values from the environment.
      *
      * @tparam R
      *   The type of value in the environment
      */
    final class UseOps[R](dummy: Unit) extends AnyVal:
        /** Applies a function to the value from the environment.
          *
          * @param f
          *   The function to apply to the environment value
          * @return
          *   A computation that applies the function to the environment value
          */
        inline def apply[A, S](inline f: R => A < S)(
            using
            inline tag: Tag[R],
            inline frame: Frame
        ): A < (Env[R] & S) =
            ContextEffect.suspendAndMap(erasedTag[R]) { map =>
                f(map.asInstanceOf[TypeMap[R]].get(using tag))
            }
    end UseOps

    /** Creates a UseOps instance for a given type. */
    inline def use[R >: Nothing]: UseOps[R] = UseOps(())

end Env




© 2015 - 2025 Weber Informatics LLC | Privacy Policy