Add foldF, cataF and emptyflatTap to OptionT#3335
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3335 +/- ##
=======================================
Coverage 92.70% 92.71%
=======================================
Files 379 379
Lines 7981 7985 +4
Branches 230 230
=======================================
+ Hits 7399 7403 +4
Misses 582 582
Continue to review full report at Codecov.
|
7b1bfed to
3dfd6bb
Compare
travisbrown
left a comment
There was a problem hiding this comment.
Looks good to me. I'm happy to resolve the merge conflict (it's just imports following a testing change) if you'd like.
# Conflicts: # tests/src/test/scala/cats/tests/OptionTSuite.scala
|
@travisbrown thank you (also for the offer to resolve the conflict)! Just fixed the formatting, all checks green now. |
travisbrown
left a comment
There was a problem hiding this comment.
Great, thanks, now we just need a second review!
| * Perform an effect if the value inside the is a `None`, leaving the value untouched. Equivalent to [[orElseF]] | ||
| * with an effect returning `None` as argument. | ||
| */ | ||
| def flatTapNone[B](f: => F[B])(implicit F: Monad[F]): OptionT[F, A] = |
There was a problem hiding this comment.
| def flatTapNone[B](f: => F[B])(implicit F: Monad[F]): OptionT[F, A] = | |
| def flatTapNone[B](ifNone: => F[B])(implicit F: Monad[F]): OptionT[F, A] = |
| * res0: List[Int] = List(23, 46) | ||
| * }}} | ||
| */ | ||
| def foldF[B](default: => F[B])(f: A => F[B])(implicit F: FlatMap[F]): F[B] = |
There was a problem hiding this comment.
| def foldF[B](default: => F[B])(f: A => F[B])(implicit F: FlatMap[F]): F[B] = | |
| def foldF[B](ifNone: => F[B])(withSome: A => F[B])(implicit F: FlatMap[F]): F[B] = |
Should we add more informative names?
There was a problem hiding this comment.
While I agree with your intention (and have hence changed it on flatTapNone – thx), I would value consistency with fold more and keep the parameter names the same.
| * one parameter list, which can result in better type inference in some | ||
| * contexts. | ||
| */ | ||
| def cataF[B](default: => F[B], f: A => F[B])(implicit F: FlatMap[F]): F[B] = |
There was a problem hiding this comment.
I am aware of the notions of catamorphisms, but is that also a unified term or notion across cats? I can only grep the words def cata in OptionTand in CoFree.
Unless we want to extend the use across the whole of cats, perhaps we should drop them, to avoid confusion.
There was a problem hiding this comment.
There's a cata to fold already, so when seeing foldF, I'd expect cataF there as well. Whether cata should have been introduced with that name in the first place seems to be outside of the scope of this PR…but that's just my two cents.
| def semiflatMap[B](f: A => F[B])(implicit F: Monad[F]): OptionT[F, B] = | ||
| flatMap(a => OptionT.liftF(f(a))) | ||
|
|
||
| def semiflatTap[B](f: A => F[B])(implicit F: Monad[F]): OptionT[F, A] = |
There was a problem hiding this comment.
We have had this conversation before: given that the B has no relevance on the types of the outputs, should we just make it an existential?
| def semiflatTap[B](f: A => F[B])(implicit F: Monad[F]): OptionT[F, A] = | |
| def semiflatTap(withSome: A => F[_])(implicit F: Monad[F]): OptionT[F, A] = |
There was a problem hiding this comment.
FlatMap has this type parameter for flatTap, EitherT has it for it's semiFlatTap, so again, I would vote for consistency to give cats users a reliable experience in terms of how signatures look and when type inference works. Or do you see any other advantage of the existential which would outweigh this aspect?
…tiont # Conflicts: # tests/src/test/scala/cats/tests/OptionTSuite.scala
|
@travisbrown As you approved the code once already and I changed only an argument name since then, would you mind merging? 🙏 |
|
Sure, I’ll merge when I’m back at a computer. |
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #3335 +/- ##
=======================================
Coverage 92.70% 92.71%
=======================================
Files 379 379
Lines 7981 7985 +4
Branches 230 230
=======================================
+ Hits 7399 7403 +4
Misses 582 582 |
Adds several handy methods to
OptionT:foldFallows to fold effectually, similar toEitherT.foldFcataFis a variant offoldFwith one parameter list, similar ascatais tofoldemptyflatTap(suggestions for better names welcome) allows to perform an effect if theOptionTcarries aNonevalue inside, leaving the result unchanged (except if raising an error, that would propagate).An example for a use case for
emptyflatTapis looking up a value in a cache (returningF[Option[V]]which you wrap inOptionTfor further handling, but logging (asF[Unit]) if the value was empty: