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

izumi.functional.bio.DivergenceHelper.scala Maven / Gradle / Ivy

package izumi.functional.bio

import izumi.functional.bio.DivergenceHelper.Nondivergent

import scala.annotation.nowarn

trait DivergenceHelper {
  type Divergence = Nondivergent
}
object DivergenceHelper {
  type Nondivergent

  object Divergent {
    /**
      * Upcast `Divergence` parameter instead of setting
      * a contradictory value as in `{ type Divergence = Divergent }`
      *
      * This allows a Divergent implicit to be _less_ specific
      * than the non-divergent instances, while at the same time
      * not matching its own requirement of `{ type Divergence = Nondivergent }`
      *
      * Note: Upcasting Divergence also depends on returning a type
      * variable instead of a known type. `Divergent.Of[SyncSafe3[F]]`
      * will not fail the Nondivergent requirement, only `Divergent.Of[C[F]]` will.
      */
    type Of[A] = A { type Divergence }
    @inline def apply[A <: DivergenceHelper, A1 >: A](a: A): Divergent.Of[A1] = a.asInstanceOf[Divergent.Of[A1]]
  }

  /**
    * Nondivergent helper does not work. To make use of
    * divergence protection, conversion implicits should use type variables
    * for summoning, instead of the direct type itself, as in:
    *
    * {{{
    *   implicit def convert1To2[C[f[_]] <: SyncSafe1[f], F[_, _], E](implicit F: C[F[Nothing, _]] { type Divergence = Nondivergent }): Divergent.Of[C[F[E, _]]]
    * }}}
    *
    * Where using `Nondivergent.Of[C[F[Nothing, _]]]` or `SyncSafe1[F[Nothing, _]] { type Divergence = Nondivergent }`
    * both will not work.
    *
    * The structural refinement must be placed directly on
    * the `C` type variable, not through an alias to work.
    */
  @nowarn("msg=never used") private object Nondivergent {
    @nowarn("msg=never used") private type Of[A] = A { type Divergence = Nondivergent }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy