Skip to content

Commit

Permalink
Add unlessM
Browse files Browse the repository at this point in the history
  • Loading branch information
m50d committed Sep 19, 2023
1 parent 85633a2 commit d61d90d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/data/OptionT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,14 @@ object OptionT extends OptionTInstances {
def unlessF[F[_], A](cond: Boolean)(fa: => F[A])(implicit F: Applicative[F]): OptionT[F, A] =
OptionT.whenF(!cond)(fa)

/**
* Creates a non-empty `OptionT[F, A]` from an `F[A]` value if the given F-condition is considered `false`.
* Otherwise, `none[F, A]` is returned. Analogous to `Option.unless` but for effectful conditions.
*/
def unlessM[F[_], A](cond: F[Boolean])(fa: => F[A])(implicit F: Monad[F]): OptionT[F, A] = OptionT(
F.ifM(cond)(ifTrue = F.pure(None), ifFalse = F.map(fa)(Some(_)))
)

/**
* Same as `unlessF`, but expressed as a FunctionK for use with mapK.
*/
Expand Down
15 changes: 15 additions & 0 deletions tests/shared/src/test/scala/cats/tests/OptionTSuite.scala
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,21 @@ class OptionTSuite extends CatsSuite {
}
}

test("OptionT.unlessM[Id, A] consistent with Option.unless") {
// Option.unless is inlined here because it is not available before Scala 2.13
def unless[A]: (Boolean, A) => Option[A] = (c: Boolean, a: A) => if (!c) Some(a) else None

forAll { (i: Int, b: Boolean) =>
assert(OptionT.unlessM[Id, Int](b)(i).value === (unless(b, i)))
}
}

test("OptionT.unlessF and OptionT.unlessM consistent") {
forAll { (li: List[Int], bs: List[Boolean]) =>
assert(bs.flatMap(OptionT.unlessF(_)(li).value) === OptionT.unlessM(bs)(li).value)
}
}

test("OptionT.unlessK and OptionT.unlessF consistent") {
forAll { (li: List[Int], b: Boolean) =>
assert(IdT(li).mapK(OptionT.unlessK(b)).value === (OptionT.unlessF(b)(li)))
Expand Down

0 comments on commit d61d90d

Please sign in to comment.