Guest User

Untitled

a guest
Jan 12th, 2019
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.38 KB | None | 0 0
  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. }
Add Comment
Please, Sign In to add comment