Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jvm/src/main/scala-2.x/src/main/scala/mouse/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package object mouse extends MouseFunctions {
object any extends AnySyntax
object anyf extends AnyFSyntax
object boolean extends BooleanSyntax
object booleanf extends BooleanFSyntax
object double extends DoubleSyntax
object feither extends FEitherSyntax
object fnested extends FNestedSyntax
Expand Down
1 change: 1 addition & 0 deletions jvm/src/main/scala-3.x/src/main/scala/mouse/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package object mouse extends MouseFunctions {
object any extends AnySyntax
object anyf extends AnyFSyntax
object boolean extends BooleanSyntax
object booleanf extends BooleanFSyntax
object double extends DoubleSyntax
object feither extends FEitherSyntax
object fnested extends FNestedSyntax
Expand Down
1 change: 1 addition & 0 deletions shared/src/main/scala-2.x/src/main/scala/mouse/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ trait AllSharedSyntax
with AnyFSyntax
with OptionSyntax
with BooleanSyntax
with BooleanFSyntax
with StringSyntax
with TrySyntax
with IntSyntax
Expand Down
1 change: 1 addition & 0 deletions shared/src/main/scala-3.x/src/main/scala/mouse/all.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ trait AllSharedSyntax
with AnyFSyntax
with OptionSyntax
with BooleanSyntax
with BooleanFSyntax
with StringSyntax
with TrySyntax
with IntSyntax
Expand Down
58 changes: 58 additions & 0 deletions shared/src/main/scala/mouse/booleanf.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package mouse

import cats.{Applicative, Functor, Monad}

trait BooleanFSyntax {

implicit final def booleanfSyntaxMouse[F[_]](fa: F[Boolean]): BooleanFOps[F] = new BooleanFOps(fa)
}

final class BooleanFOps[F[_]](private val fa: F[Boolean]) extends AnyVal {

def &&(fb: => F[Boolean])(implicit F: Monad[F]): F[Boolean] =
F.flatMap(fa) {
case true => fb
case false => F.pure(false)
}

def &&(b: => Boolean)(implicit F: Functor[F]): F[Boolean] =
F.map(fa) {
case true => b
case false => false
}

def ||(fb: => F[Boolean])(implicit F: Monad[F]): F[Boolean] =
F.flatMap(fa) {
case true => F.pure(true)
case false => fb
}

def ||(b: => Boolean)(implicit F: Functor[F]): F[Boolean] =
F.map(fa) {
case true => true
case false => b
}

def &(fb: F[Boolean])(implicit F: Applicative[F]): F[Boolean] =
F.ap(F.map(fa)(a => b => a && b))(fb)

def &(b: Boolean)(implicit F: Functor[F]): F[Boolean] =
F.map(fa)(_ && b)

def |(fb: F[Boolean])(implicit F: Applicative[F]): F[Boolean] =
F.ap(F.map(fa)(a => b => a || b))(fb)

def |(b: Boolean)(implicit F: Functor[F]): F[Boolean] =
F.map(fa)(_ || b)

def ^(fb: F[Boolean])(implicit F: Monad[F]): F[Boolean] =
F.flatMap(fa) { a =>
F.flatMap(fb) { b => F.pure(a ^ b) }
}

def ^(b: Boolean)(implicit F: Functor[F]): F[Boolean] =
F.map(fa) { _ ^ b }

def unary_!(implicit F: Functor[F]): F[Boolean] =
F.map(fa)(!_)
}
64 changes: 64 additions & 0 deletions shared/src/test/scala/mouse/BooleanFSyntaxTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package mouse

import cats.instances.either._
import cats.syntax.either._

class BooleanFSyntaxTest extends MouseSuite {

test("BooleanFSyntax.&&.F") {
assertEquals(true.asRight[Int] && true.asRight[Int], Right(true))
assertEquals(true.asRight[Int] && false.asRight[Int], Right(false))
assertEquals(false.asRight[Int] && true.asRight[Int], Right(false))
assertEquals(false.asRight[Int] && false.asRight[Int], Right(false))
assertEquals(true.asRight[Unit] && ().asLeft[Boolean], Left(()))
assertEquals(().asLeft[Boolean] && false.asRight[Unit], Left(()))
}

test("BooleanFSyntax.&&") {
assertEquals(true.asRight[Int] && true, Right(true))
assertEquals(true.asRight[Int] && false, Right(false))
assertEquals(false.asRight[Int] && true, Right(false))
assertEquals(false.asRight[Int] && false, Right(false))
assertEquals(().asLeft[Boolean] && false, Left(()))
}

test("BooleanFSyntax.||.F") {
assertEquals(true.asRight[Int] || true.asRight[Int], Right(true))
assertEquals(true.asRight[Int] || false.asRight[Int], Right(true))
assertEquals(false.asRight[Int] || true.asRight[Int], Right(true))
assertEquals(false.asRight[Int] || false.asRight[Int], Right(false))
assertEquals(true.asRight[Unit] || ().asLeft[Boolean], Right(true))
assertEquals(().asLeft[Boolean] || false.asRight[Unit], Left(()))
}

test("BooleanFSyntax.||") {
assertEquals(true.asRight[Int] || true, Right(true))
assertEquals(true.asRight[Int] || false, Right(true))
assertEquals(false.asRight[Int] || true, Right(true))
assertEquals(false.asRight[Int] || false, Right(false))
assertEquals(().asLeft[Boolean] || false, Left(()))
}

test("BooleanFSyntax.^.F") {
assertEquals(true.asRight[Int] ^ true.asRight[Int], Right(false))
assertEquals(true.asRight[Int] ^ false.asRight[Int], Right(true))
assertEquals(false.asRight[Int] ^ true.asRight[Int], Right(true))
assertEquals(false.asRight[Int] ^ false.asRight[Int], Right(false))
assertEquals(true.asRight[Unit] ^ ().asLeft[Boolean], Left(()))
assertEquals(().asLeft[Boolean] ^ false.asRight[Unit], Left(()))
}

test("BooleanFSyntax.^") {
assertEquals(true.asRight[Int] ^ true, Right(false))
assertEquals(true.asRight[Int] ^ false, Right(true))
assertEquals(false.asRight[Int] ^ true, Right(true))
assertEquals(false.asRight[Int] ^ false, Right(false))
assertEquals(().asLeft[Boolean] ^ false, Left(()))
}

test("BooleanFSyntax.!") {
assertEquals(!true.asRight[Int], Right(false))
assertEquals(!false.asRight[Int], Right(true))
assertEquals(!().asLeft[Boolean], Left(()))
}
}