io.hireproof.structure.Structure.scala Maven / Gradle / Ivy
The newest version!
package io.hireproof.structure
import cats.data.Validated
import cats.syntax.all._
import io.hireproof.screening.Validation
trait Structure[A] {
type Self[a] <: Structure[a]
private[structure] def vimap[T](
f: A => Validated[Errors, T],
g: T => A,
validation: Option[Validation[_, _]]
): Self[T]
final def imap[T](f: A => T)(g: T => A): Self[T] = vimap(f(_).valid, g, none)
final def const(value: => A): Self[Unit] = imap(_ => ())(_ => value)
final def ivalidate[T](validation: Validation[A, T])(g: T => A): Self[T] =
vimap(validation.run(_).leftMap(Errors.root), g, validation.some)
final def validate(validation: Validation[A, A]): Self[A] = ivalidate(validation)(identity)
final def merge[T](implicit evidence: Evidence.Product.Merger.Aux[A, T]): Self[T] = imap(evidence.to)(evidence.from)
}
object Structure {
type Aux[A, S[_]] = Structure[A] { type Self[a] = S[a] }
trait Product[A] extends Structure[A] {
type Element[a]
type Group[a] <: Structure.Aux[a, Group]
def zipAll[T](group: Group[T]): Group[A |*| T]
def zip[T](element: Element[T]): Group[A |*| T]
final def |*|[T](element: Element[T])(implicit evidence: Evidence.Product.Merger[A |*| T]): Group[evidence.Out] =
(this zip element).merge(evidence)
final def ximap[T](implicit evidence: Evidence.Product.Aux[T, A]): Self[T] = imap(evidence.from)(evidence.to)
}
trait Sum[A] extends Structure[A] {
type Element[a]
type Group[a] <: Structure.Aux[a, Group]
def orElseAll[T](group: Group[T]): Group[A |+| T]
def orElse[T](element: Element[T]): Group[A |+| T]
final def |+|[T](element: Element[T]): Group[A |+| T] = this orElse element
final def ximap[T](implicit evidence: Evidence.Sum.Aux[T, A]): Self[T] = imap(evidence.from)(evidence.to)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy