
endpoints4s.InvariantFunctor.scala Maven / Gradle / Ivy
The newest version!
package endpoints4s
/** Defines ways to transform a given type constructor F */
trait InvariantFunctor[F[_]] {
/**
* Transforms an `F[A]` value into an `F[B]` value given a pair
* of functions from `A` to `B` and from `B` to `A`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
def xmap[A, B](fa: F[A], f: A => B, g: B => A): F[B]
}
/** Provides extensions methods for values of type [[InvariantFunctor]] */
trait InvariantFunctorSyntax {
/**
* Extension methods for values of type `F[A]` for which there is an implicit
* `InvariantFunctor[F]` instance.
*/
implicit class InvariantFunctorSyntax[A, F[_]](val fa: F[A])(implicit
ev: InvariantFunctor[F]
) {
/**
* Transforms an `F[A]` value into an `F[B]` value given a pair
* of functions from `A` to `B` and from `B` to `A`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
def xmap[B](f: A => B)(g: B => A): F[B] = ev.xmap(fa, f, g)
}
}
/** Given a type constructor `F`, a partial function `A => Validated[B]`
* and a total function `B => A`, turns an `F[A]` into an `F[B]`.
*
* A partial invariant functor is an invariant functor whose covariant
* transformation function is total (ie, `A => Valid[B]`).
*/
trait PartialInvariantFunctor[F[_]] extends InvariantFunctor[F] {
/**
* Transforms an `F[A]` value into an `F[B]` value given a partial function
* from `A` to `B`, and a total function from `B` to `A`.
*
* This is useful to ''refine'' the type `A` into a possibly smaller type `B`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
def xmapPartial[A, B](fa: F[A], f: A => Validated[B], g: B => A): F[B]
/**
* Transforms an `F[A]` value into an `F[B]` value given a `Codec[A, B]`.
*
* This is useful to ''refine'' the type `A` into a possibly smaller type `B`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
final def xmapWithCodec[A, B](fa: F[A], codec: Codec[A, B]): F[B] =
xmapPartial(fa, codec.decode, codec.encode)
def xmap[A, B](fa: F[A], f: A => B, g: B => A): F[B] =
xmapPartial[A, B](fa, a => Valid(f(a)), g)
}
/** Provides extension methods for values of type [[PartialInvariantFunctor]] */
trait PartialInvariantFunctorSyntax extends InvariantFunctorSyntax {
implicit class PartialInvariantFunctorSyntax[A, F[_]](val fa: F[A])(implicit
ev: PartialInvariantFunctor[F]
) {
/**
* Transforms an `F[A]` value into an `F[B]` value given a partial function
* from `A` to `B`, and a total function from `B` to `A`.
*
* This is useful to ''refine'' the type `A` into a possibly smaller type `B`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
def xmapPartial[B](f: A => Validated[B])(g: B => A): F[B] =
ev.xmapPartial(fa, f, g)
/**
* Transforms an `F[A]` value into an `F[B]` value given a `Codec[A, B]`.
*
* This is useful to ''refine'' the type `A` into a possibly smaller type `B`.
*
* @see [[http://julienrf.github.io/endpoints/algebras/endpoints.html#transforming-and-refining-url-constituents Some examples]]
*/
def xmapWithCodec[B](codec: Codec[A, B]): F[B] =
ev.xmapWithCodec(fa, codec)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy