Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package quantified
- import cats.Monad
- import scala.language.implicitConversions
- /** C[_] constraint applied to type F[_, _] quantified in first parameter */
- final class Quant[+C[_[_]], F[_, _]] private (private val erased: C[F[Any, ?]]) extends AnyVal {
- type State = Defined
- @inline def underlying[E]: C[F[E, ?]] = erased.asInstanceOf[C[F[E, ?]]]
- }
- object Quant extends QuantImplicits {
- @inline final def apply[C[_[_]], F[_, _]](implicit q: Quant[C, F]): Quant[C, F] = q
- final def apply[C[_[_]]]: QuantApply[C] = new QuantApply[C]()
- private[Quant] final class QuantApply[C[_[_]]](private val dummy: Boolean = false) extends AnyVal {
- def apply[F[_, _], E](c: C[F[E, ?]]): Quant[C, F] = new Quant[C, F](c.asInstanceOf[C[F[Any, ?]]])
- }
- private sealed trait Private {
- private[Quant] type T
- }
- private[Quant] final val Private = new Private {}
- /** If somehow there's an instance that's valid for a fresh private type T >: Nothing <: Any,
- it means that this instance must be a polymorphic instance valid for all type parameters X >: Nothing <: Any **/
- implicit def fromImplicitDef[C[_[_]], F[_, _]](implicit lp: shapeless.LowPriority, c: C[F[Private.T, ?]]): Quant[C, F] { type State = Derived } =
- Quant[C].apply(c.asInstanceOf[C[F[Any, ?]]]).asInstanceOf[Quant[C, F] { type State = Derived }]
- }
- trait QuantImplicits extends Any {
- final type Monad2[F[_, _]] = Quant[Monad, F]
- object Monad2 {
- final def apply[F[_, _]: Monad2]: Monad2[F] = implicitly[Quant.Monad2[F]]
- implicit final class Monad2CovariantFlatMap[F[+_, _], E, A](self: F[E, A])(implicit ev: Monad2[F] { type State = Defined }) {
- @inline def flatMap[E1 >: E, B](f: A => F[E1, B]): F[E1, B] =
- apply[F].apply[E1].flatMap(self)(f)
- @inline def *>[E1 >: E, B](f: => F[E1, B]): F[E1, B] =
- flatMap[E1, B](_ => f)
- }
- }
- @inline implicit final def instantiate[C[_[_]], F[_, _], E](implicit lp: shapeless.LowPriority, q: Quant[C, F] { type State = Defined }): C[F[E, ?]] = q.underlying
- // Also works via Param:
- // @inline implicit final def instantiate[C[_[_]], F[_, _], E](implicit lp: shapeless.LowPriority, c: Param[Lambda[E => C[F[E, ?]]]] { type State = Defined }): C[F[E, ?]] = c.underlying
- @inline implicit final def conversion[C[_[_]], F[_, _], E](q: Quant[C, F]): C[F[E, ?]] = q.underlying
- }
- private[quantified] trait Defined
- private[quantified] trait Derived
- /** Universally quantified instance for C */
- final class Param[C[_]](private val erased: C[_]) {
- type State = Defined
- def underlying[A]: C[A] = erased.asInstanceOf[C[A]]
- }
- object Param extends ParamImplicits {
- def apply[C[_]: Param]: Param[C] = implicitly
- private sealed trait Private {
- private[Param] trait T extends Any
- }
- private[Param] final val Private = new Private {}
- /** If there's somehow an instance for a fresh private type >: Nothing <: Any,
- it means that this instance is a polymorphic instance valid for all type parameters >: Nothing <: Any **/
- implicit def fromImplicitDef[C[_]](implicit lp: shapeless.LowPriority, c: C[Private.T]): Param[C] { type State = Derived } =
- new Param(c).asInstanceOf[Param[C] { type State = Derived }]
- }
- trait ParamImplicits {
- @inline implicit final def instantiate[C[_], A](implicit lp: shapeless.LowPriority, c: Param[C] { type State = Defined }): C[A] = c.underlying
- @inline implicit final def conversion[C[_], A](c: Param[C]): C[A] = c.underlying
- }
Add Comment
Please, Sign In to add comment