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

monocle.generic.internal.CoproductToDisjunction.scala Maven / Gradle / Ivy

The newest version!
package monocle.generic.internal

import shapeless._

/** Typeclass converting a `shapeless.Coproduct` to an `scala.Either`.
  *
  * Based on `shapeless.ops.coproduct.CoproductToEither`:
  * https://github.com/milessabin/shapeless/blob/shapeless-2.3.3-scala-2.13.0-M4/core/src/main/scala/shapeless/ops/coproduct.scala#L1275-L1303
  */
sealed trait CoproductToDisjunction[C <: Coproduct] extends DepFn1[C] with Serializable

object CoproductToDisjunction {
  type Aux[In <: Coproduct, Out0] = CoproductToDisjunction[In] { type Out = Out0 }

  implicit def baseToEither[L, R]: CoproductToDisjunction.Aux[L :+: R :+: CNil, Either[L, R]] =
    new CoproductToDisjunction[L :+: R :+: CNil] {
      type Out = Either[L, R]
      def apply(t: L :+: R :+: CNil): Either[L, R] =
        t match {
          case Inl(l)         => Left(l)
          case Inr(Inl(r))    => Right(r)
          case Inr(Inr(cnil)) => cnil.impossible
        }
    }

  implicit def cconsToEither[L, R <: Coproduct, Out0](implicit
    evR: CoproductToDisjunction.Aux[R, Out0]
  ): CoproductToDisjunction.Aux[L :+: R, Either[L, Out0]] =
    new CoproductToDisjunction[L :+: R] {
      type Out = Either[L, Out0]
      def apply(t: L :+: R): Either[L, Out0] =
        t match {
          case Inl(l) => Left(l)
          case Inr(r) => Right(evR(r))
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy