io.scalaland.chimney.cats.CatsPartialTransformerImplicits.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of chimney-cats_sjs1_3 Show documentation
Show all versions of chimney-cats_sjs1_3 Show documentation
Integrations with selected Cats data types and type classes
The newest version!
package io.scalaland.chimney.cats
import _root_.cats.{~>, Alternative, Applicative, CoflatMap, Contravariant, Monad, MonadError, Parallel}
import _root_.cats.arrow.{ArrowChoice, CommutativeArrow, FunctionK}
import io.scalaland.chimney.partial
import io.scalaland.chimney.PartialTransformer
/** @since 0.7.0 */
trait CatsPartialTransformerImplicits {
/** @since 1.0.0 */
implicit final val catsArrowForPartialTransformer
: ArrowChoice[PartialTransformer] & CommutativeArrow[PartialTransformer] =
new ArrowChoice[PartialTransformer] with CommutativeArrow[PartialTransformer] {
override def lift[A, B](f: A => B): PartialTransformer[A, B] = PartialTransformer.fromFunction(f)
override def first[A, B, C](fa: PartialTransformer[A, B]): PartialTransformer[(A, C), (B, C)] =
(pair, failFast) => fa.transform(pair._1, failFast).map(_ -> pair._2)
override def compose[A, B, C](
f: PartialTransformer[B, C],
g: PartialTransformer[A, B]
): PartialTransformer[A, C] =
(a, failFast) => g.transform(a, failFast).flatMap(b => f.transform(b, failFast))
override def choose[A, B, C, D](
f: PartialTransformer[A, C]
)(
g: PartialTransformer[B, D]
): PartialTransformer[Either[A, B], Either[C, D]] = (ab: Either[A, B], failFast: Boolean) =>
ab match {
case Left(a) => f.transform(a, failFast).map(Left(_))
case Right(b) => g.transform(b, failFast).map(Right(_))
}
}
/** @since 1.0.0 */
implicit final def catsCovariantForPartialTransformer[Source]
: MonadError[PartialTransformer[Source, *], partial.Result.Errors] &
CoflatMap[PartialTransformer[Source, *]] &
Alternative[PartialTransformer[Source, *]] =
new MonadError[PartialTransformer[Source, *], partial.Result.Errors]
with CoflatMap[PartialTransformer[Source, *]]
with Alternative[PartialTransformer[Source, *]] {
override def pure[A](x: A): PartialTransformer[Source, A] = (_, _) => partial.Result.Value(x)
override def flatMap[A, B](fa: PartialTransformer[Source, A])(
f: A => PartialTransformer[Source, B]
): PartialTransformer[Source, B] =
(src, failFast) => fa.transform(src, failFast).flatMap(a => f(a).transform(src, failFast))
override def tailRecM[A, B](a: A)(
f: A => PartialTransformer[Source, Either[A, B]]
): PartialTransformer[Source, B] =
(src, failFast) => {
def run(a1: A) = partial.Result.fromCatching(f(a1).transform(src, failFast)).flatMap(identity)
@scala.annotation.tailrec
def loop(a1: A): partial.Result[B] = run(a1) match {
case partial.Result.Value(Left(a2)) => loop(a2)
case partial.Result.Value(Right(b)) => partial.Result.Value(b)
case errors => errors.asInstanceOf[partial.Result[B]]
}
loop(a)
}
override def raiseError[A](e: partial.Result.Errors): PartialTransformer[Source, A] = (_, _) => e
override def handleErrorWith[A](fa: PartialTransformer[Source, A])(
f: partial.Result.Errors => PartialTransformer[Source, A]
): PartialTransformer[Source, A] = (a, failFast) =>
try
fa.transform(a, failFast) match {
case errors: partial.Result.Errors => f(errors).transform(a, failFast)
case value => value
}
catch {
case err: Throwable => partial.Result.fromErrorThrowable(err)
}
override def coflatMap[A, B](
fa: PartialTransformer[Source, A]
)(
f: PartialTransformer[Source, A] => B
): PartialTransformer[Source, B] = (src, _) => partial.Result.fromCatching(f(fa))
override def empty[A]: PartialTransformer[Source, A] = (_, _) => partial.Result.fromEmpty[A]
override def combineK[A](
x: PartialTransformer[Source, A],
y: PartialTransformer[Source, A]
): PartialTransformer[Source, A] = (src, failFast) =>
x.transform(src, failFast).orElse(y.transform(src, failFast))
}
/** @since 1.0.0 */
implicit final def catsParallelForPartialTransformer[Source]: Parallel[PartialTransformer[Source, *]] {
type F[A] = PartialTransformer[Source, A]
} =
new Parallel[PartialTransformer[Source, *]] {
override type F[A] = PartialTransformer[Source, A]
def parallel: PartialTransformer[Source, *] ~> PartialTransformer[Source, *] = FunctionK.id
def sequential: PartialTransformer[Source, *] ~> PartialTransformer[Source, *] = FunctionK.id
val applicative: Applicative[PartialTransformer[Source, *]] = new Applicative[PartialTransformer[Source, *]] {
def pure[A](x: A): PartialTransformer[Source, A] = (_, _) => partial.Result.Value(x)
def ap[A, B](ff: PartialTransformer[Source, A => B])(
fa: PartialTransformer[Source, A]
): PartialTransformer[Source, B] =
(src, failFast) =>
partial.Result.map2[A => B, A, B](
ff.transform(src, failFast),
fa.transform(src, failFast),
(f, a) => f(a),
failFast
)
}
val monad: Monad[PartialTransformer[Source, *]] = catsCovariantForPartialTransformer[Source]
}
/** @since 1.0.0 */
implicit final def catsContravariantForPartialTransformer[Target]: Contravariant[PartialTransformer[*, Target]] =
new Contravariant[PartialTransformer[*, Target]] {
def contramap[A, B](fa: PartialTransformer[A, Target])(f: B => A): PartialTransformer[B, Target] =
(b, failFast) => partial.Result.fromCatching(f(b)).flatMap(a => fa.transform(a, failFast))
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy