Skip to content

Instantly share code, notes, and snippets.

@sir-wabbit
Last active December 5, 2016 17:41
Show Gist options
  • Select an option

  • Save sir-wabbit/e94d9d77126532cc55d6f1ca80ee9193 to your computer and use it in GitHub Desktop.

Select an option

Save sir-wabbit/e94d9d77126532cc55d6f1ca80ee9193 to your computer and use it in GitHub Desktop.
import cats.{Applicative, Monad}
import cats.kernel.Monoid
object QuantifiedContexts {
trait Forall[F[_]] { def apply[A]: F[A] }
trait Exists[F[_]] { type A; def apply: F[A] }
type MonoidK[F[_]] = Forall[λ[X => Monoid[F[X]]]]
final case class Alternative[F[_]](applicative: Applicative[F], monoid: MonoidK[F])
final case class MonadPlus[F[_]](monad: Monad[F], monoid: MonoidK[F])
val optionMonoidK: MonoidK[Option] = new MonoidK[Option] {
override def apply[A]: Monoid[Option[A]] = new Monoid[Option[A]] {
override def empty: Option[A] = None
override def combine(a: Option[A], b: Option[A]): Option[A] = a.orElse(b)
}
}
implicit val optionMonadPlus: MonadPlus[Option] = MonadPlus(Monad[Option], optionMonoidK)
implicit val optionAlternative: Alternative[Option] = Alternative(Applicative[Option], optionMonoidK)
implicit class MonadPlusOps[F[_], A](fa: F[A])(implicit F: MonadPlus[F]) {
def map[B](f: A => B): F[B] = F.monad.map(fa)(f)
def bind[B](f: A => F[B]): F[B] = F.monad.flatMap(fa)(f)
def <|>(fb: F[A]): F[A] = F.monoid.apply[A].combine(fa, fb)
}
val a = Option(1)
val b = None
val c = a <|> b
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment