-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Add flatTapIn
and flatTapF
to FOptionSyntax
and FEitherSyntax
#488
✨ Add flatTapIn
and flatTapF
to FOptionSyntax
and FEitherSyntax
#488
Conversation
Thank you @jwojnowski I'm curious.. what do you use these operators for "in the wild"? I associate My concern is that the unit tests don't motivate these operations. They check contrived data but nowhere can a reader discover the intended purpose/usage of the ops, other than from the type signatures. I also wonder if |
@benhutchison the use case I had in mind is subsequent validation of an Regarding the tests: true, I focused on testing the behaviour while keeping them consistent with the existing tests. I guess we can make them reflect the above use case. A quick debugging with def semiflatTap[B](f: R => F[B]): F[Either[L, R] |
@jwojnowski Im still not getting you. the flatTap family of operations perform a side effect and throw away the returned value. therefore, the value they return is irrelevant to the program. only the effect is relevant. So signatures with pure functions will achieve nothing, such as (& Option same)?
The |
I agree, the value is thrown away, the effect is relevant. However, we’re diverging on which effect the In my mind, the Let’s consider an example on import cats.implicits._
val eitherWithPositive: Either[String, Int] = Right(42)
val eitherWithNegative: Either[String, Int] = Right(-24)
def validatePositive(value: Int): Either[String, Unit] =
Either.raiseUnless(value > 0)(s"Value must be positive, but was $value")
val positiveResult = eitherWithPositive.flatTap(validatePositive) // Right(42) // still 42 despite validatePositive returning Unit
val negativeResult = eitherWithNegative.flatTap(validatePositive) // Left(Value must be positive, but was -24) Now, let’s do the same, but within context of type F[A] = Try[A]
val fEitherWithPositive: F[Either[String, Int]] = Try(Right(42))
val fEitherWithNegative: F[Either[String, Int]] = Try(Right(-24))
val positiveFResult = fEitherWithPositive.flatTapIn(validatePositive) // Success(Right(42)) // still 42, despite validatePositive returning Unit
val negativeFResult = fEitherWithNegative.flatTapIn(validatePositive) // Success(Left(Value must be positive, but was -24)) The same applies to Does this example explain the idea? |
OK, from the description I can see there what looks (to me) a narrow set of situations where However, I think these methods will find one user atm, namely @jwojnowski. Im not convinced they will find wider usage. In this example use case, it seems to work around a validation of There's a clear workaround for the lack of these methods ( Im going to close the PR. Criteria for re-opening:
|
Hi!
I found myself missing
flatTap
versions onF[Either[...]]
andF[Option[...]]
enough times to propose this small change 😉