Skip to content

Commit a6a3e38

Browse files
authored
Merge pull request #4519 from m50d/unlessm
Add `OptionT#unlessM`
2 parents 85633a2 + d61d90d commit a6a3e38

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

core/src/main/scala/cats/data/OptionT.scala

+8
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,14 @@ object OptionT extends OptionTInstances {
787787
def unlessF[F[_], A](cond: Boolean)(fa: => F[A])(implicit F: Applicative[F]): OptionT[F, A] =
788788
OptionT.whenF(!cond)(fa)
789789

790+
/**
791+
* Creates a non-empty `OptionT[F, A]` from an `F[A]` value if the given F-condition is considered `false`.
792+
* Otherwise, `none[F, A]` is returned. Analogous to `Option.unless` but for effectful conditions.
793+
*/
794+
def unlessM[F[_], A](cond: F[Boolean])(fa: => F[A])(implicit F: Monad[F]): OptionT[F, A] = OptionT(
795+
F.ifM(cond)(ifTrue = F.pure(None), ifFalse = F.map(fa)(Some(_)))
796+
)
797+
790798
/**
791799
* Same as `unlessF`, but expressed as a FunctionK for use with mapK.
792800
*/

tests/shared/src/test/scala/cats/tests/OptionTSuite.scala

+15
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,21 @@ class OptionTSuite extends CatsSuite {
421421
}
422422
}
423423

424+
test("OptionT.unlessM[Id, A] consistent with Option.unless") {
425+
// Option.unless is inlined here because it is not available before Scala 2.13
426+
def unless[A]: (Boolean, A) => Option[A] = (c: Boolean, a: A) => if (!c) Some(a) else None
427+
428+
forAll { (i: Int, b: Boolean) =>
429+
assert(OptionT.unlessM[Id, Int](b)(i).value === (unless(b, i)))
430+
}
431+
}
432+
433+
test("OptionT.unlessF and OptionT.unlessM consistent") {
434+
forAll { (li: List[Int], bs: List[Boolean]) =>
435+
assert(bs.flatMap(OptionT.unlessF(_)(li).value) === OptionT.unlessM(bs)(li).value)
436+
}
437+
}
438+
424439
test("OptionT.unlessK and OptionT.unlessF consistent") {
425440
forAll { (li: List[Int], b: Boolean) =>
426441
assert(IdT(li).mapK(OptionT.unlessK(b)).value === (OptionT.unlessF(b)(li)))

0 commit comments

Comments
 (0)