daily pastebin goal
9%
SHARE
TWEET

Untitled

a guest Jan 12th, 2019 49 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package quantified
  2.  
  3. import cats.Monad
  4.  
  5. import scala.language.implicitConversions
  6.  
  7. /** C[_] constraint applied to type F[_, _] quantified in first parameter */
  8. final class Quant[+C[_[_]], F[_, _]] private (private val erased: C[F[Any, ?]]) extends AnyVal {
  9.   type State = Defined
  10.  
  11.   @inline def underlying[E]: C[F[E, ?]] = erased.asInstanceOf[C[F[E, ?]]]
  12. }
  13.  
  14. object Quant extends QuantImplicits {
  15.  
  16.   @inline final def apply[C[_[_]], F[_, _]](implicit q: Quant[C, F]): Quant[C, F] = q
  17.   final def apply[C[_[_]]]: QuantApply[C] = new QuantApply[C]()
  18.  
  19.   private[Quant] final class QuantApply[C[_[_]]](private val dummy: Boolean = false) extends AnyVal {
  20.     def apply[F[_, _], E](c: C[F[E, ?]]): Quant[C, F] = new Quant[C, F](c.asInstanceOf[C[F[Any, ?]]])
  21.   }
  22.  
  23.   private sealed trait Private {
  24.     private[Quant] type T
  25.   }
  26.   private[Quant] final val Private = new Private {}
  27.  
  28.   /** If somehow there's an instance that's valid for a fresh private type T >: Nothing <: Any,
  29.       it means that this instance must be a polymorphic instance valid for all type parameters X >: Nothing <: Any **/
  30.   implicit def fromImplicitDef[C[_[_]], F[_, _]](implicit lp: shapeless.LowPriority, c: C[F[Private.T, ?]]): Quant[C, F] { type State = Derived } =
  31.     Quant[C].apply(c.asInstanceOf[C[F[Any, ?]]]).asInstanceOf[Quant[C, F] { type State = Derived }]
  32. }
  33.  
  34. trait QuantImplicits extends Any {
  35.   final type Monad2[F[_, _]] = Quant[Monad, F]
  36.   object Monad2 {
  37.     final def apply[F[_, _]: Monad2]: Monad2[F] = implicitly[Quant.Monad2[F]]
  38.  
  39.     implicit final class Monad2CovariantFlatMap[F[+_, _], E, A](self: F[E, A])(implicit ev: Monad2[F] { type State = Defined }) {
  40.       @inline def flatMap[E1 >: E, B](f: A => F[E1, B]): F[E1, B] =
  41.         apply[F].apply[E1].flatMap(self)(f)
  42.  
  43.       @inline def *>[E1 >: E, B](f: => F[E1, B]): F[E1, B] =
  44.         flatMap[E1, B](_ => f)
  45.     }
  46.   }
  47.  
  48.   @inline implicit final def instantiate[C[_[_]], F[_, _], E](implicit lp: shapeless.LowPriority, q: Quant[C, F] { type State = Defined }): C[F[E, ?]] = q.underlying
  49.  
  50.   // Also works via Param:
  51. //  @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
  52.  
  53.   @inline implicit final def conversion[C[_[_]], F[_, _], E](q: Quant[C, F]): C[F[E, ?]] = q.underlying
  54. }
  55.  
  56. private[quantified] trait Defined
  57. private[quantified] trait Derived
  58.  
  59. /** Universally quantified instance for C */
  60. final class Param[C[_]](private val erased: C[_]) {
  61.   type State = Defined
  62.  
  63.   def underlying[A]: C[A] = erased.asInstanceOf[C[A]]
  64. }
  65.  
  66. object Param extends ParamImplicits {
  67.   def apply[C[_]: Param]: Param[C] = implicitly
  68.  
  69.   private sealed trait Private {
  70.     private[Param] trait T extends Any
  71.   }
  72.   private[Param] final val Private = new Private {}
  73.  
  74.   /** If there's somehow an instance for a fresh private type >: Nothing <: Any,
  75.       it means that this instance is a polymorphic instance valid for all type parameters >: Nothing <: Any **/
  76.   implicit def fromImplicitDef[C[_]](implicit lp: shapeless.LowPriority, c: C[Private.T]): Param[C] { type State = Derived } =
  77.     new Param(c).asInstanceOf[Param[C] { type State = Derived }]
  78. }
  79.  
  80. trait ParamImplicits {
  81.   @inline implicit final def instantiate[C[_], A](implicit lp: shapeless.LowPriority, c: Param[C] { type State = Defined }): C[A] = c.underlying
  82.  
  83.   @inline implicit final def conversion[C[_], A](c: Param[C]): C[A] = c.underlying
  84. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand