File tree 2 files changed +23
-0
lines changed
core/src/main/scala/cats/data
tests/shared/src/test/scala/cats/tests
2 files changed +23
-0
lines changed Original file line number Diff line number Diff line change @@ -787,6 +787,14 @@ object OptionT extends OptionTInstances {
787
787
def unlessF [F [_], A ](cond : Boolean )(fa : => F [A ])(implicit F : Applicative [F ]): OptionT [F , A ] =
788
788
OptionT .whenF(! cond)(fa)
789
789
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
+
790
798
/**
791
799
* Same as `unlessF`, but expressed as a FunctionK for use with mapK.
792
800
*/
Original file line number Diff line number Diff line change @@ -421,6 +421,21 @@ class OptionTSuite extends CatsSuite {
421
421
}
422
422
}
423
423
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
+
424
439
test(" OptionT.unlessK and OptionT.unlessF consistent" ) {
425
440
forAll { (li : List [Int ], b : Boolean ) =>
426
441
assert(IdT (li).mapK(OptionT .unlessK(b)).value === (OptionT .unlessF(b)(li)))
You can’t perform that action at this time.
0 commit comments