trait ToBooleanMOps {
implicit def ToBooleanMOps[M[_]](m: M[Boolean]): BooleanMOps[M] = new BooleanMOps[M](m)
}
private object BooleanM {
def True[M[_]: Monad]: M[Boolean] = Monad[M].pure(true)
def False[M[_]: Monad]: M[Boolean] = Monad[M].pure(false)
def Negate[M[_]: Functor](m: M[Boolean]): M[Boolean] = Functor[M].map(m)(!_)
}
final class BooleanMOps[M[_]](val self: M[Boolean]) extends AnyVal with Ops[M[Boolean]] {
import BooleanM._
def negateM (implicit M: Functor[M]): M[Boolean] = Negate(self)
def orM (that: => M[Boolean])(implicit M: Monad[M]): M[Boolean] = M.ifM(self, True, that)
def andM (that: => M[Boolean])(implicit M: Monad[M]): M[Boolean] = M.ifM(self, that, False)
def impliesM(that: => M[Boolean])(implicit M: Monad[M]): M[Boolean] = M.ifM(self, that, True)
def iffM (that: M[Boolean])(implicit M: Monad[M]): M[Boolean] = M.ifM(self, that, Negate(that))
def xorM (that: M[Boolean])(implicit M: Monad[M]): M[Boolean] = M.ifM(self, Negate(that), that)
def norM (that: => M[Boolean])(implicit M: Monad[M]): M[Boolean] = Negate(orM(that))
def nandM (that: => M[Boolean])(implicit M: Monad[M]): M[Boolean] = Negate(andM(that))
def ifTrueM [A](that: => M[A])(implicit M: Monad[M]): M[Unit] = whenM_(that)
def ifFalseM [A](that: => M[A])(implicit M: Monad[M]): M[Unit] = unlessM_(that)
def whenM_ [A](that: => M[A])(implicit M: Monad[M]): M[Unit] = M.bind(self)(b => M.whenM (b)(that))
def unlessM_ [A](that: => M[A])(implicit M: Monad[M]): M[Unit] = M.bind(self)(b => M.unlessM(b)(that))
}