-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Deprecate FlatMap's >> and << #1955
Deprecate FlatMap's >> and << #1955
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1955 +/- ##
==========================================
- Coverage 96.14% 96.09% -0.05%
==========================================
Files 273 273
Lines 4535 4536 +1
Branches 117 132 +15
==========================================
- Hits 4360 4359 -1
- Misses 175 177 +2
Continue to review full report at Codecov.
|
core/src/main/scala/cats/Apply.scala
Outdated
@@ -19,6 +19,14 @@ trait Apply[F[_]] extends Functor[F] with Cartesian[F] with ApplyArityFunctions[ | |||
override def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] = | |||
ap(map(fa)(a => (b: B) => (a, b)))(fb) | |||
|
|||
/** Sequentially compose two actions, discarding any value produced by the first. */ | |||
def followedBy[A, B](fa: F[A])(fb: F[B]): F[B] = | |||
map(product(fa, fb)) { case (_, b) => b } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn’t we use map2 here since that can sometimes be more efficient than product + map
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's a great idea
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also I think "sequentially" is confusing now. It is sequential if we have a monad, if we have an applicative it is not necessarily "sequential"
@@ -14,6 +14,12 @@ import simulacrum.typeclass | |||
*/ | |||
@typeclass trait Cartesian[F[_]] { | |||
def product[A, B](fa: F[A], fb: F[B]): F[(A, B)] | |||
|
|||
@inline final def *>[A, B](fa: F[A])(fb: F[B])(implicit F: Functor[F]): F[B] = | |||
F.map(product(fa, fb)) { case (_, b) => b } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t like this. If you have a Functor for Cartesian you have an Apply, no?
I’m -1 in accepting other type classes on F in methods for a typeclass of F in most cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I don’t see why these aren’t exactly symbols for the methods you moved to Apply.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add these as aliases for those in apply :)
@@ -17,10 +17,4 @@ abstract class CartesianOps[F[_], A] extends Cartesian.Ops[F, A] { | |||
final def |@|[B](fb: F[B]): CartesianBuilder[F]#CartesianBuilder2[A, B] = | |||
new CartesianBuilder[F] |@| self |@| fb | |||
|
|||
final def *>[B](fb: F[B])(implicit F: Functor[F]): F[B] = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh. I see someone put them here originally. This was an error in my view. They should be on Apply.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah +1 on that :)
@@ -215,8 +215,6 @@ All other symbols can be imported with `import cats.implicits._` | |||
| `x === y` | equals | | `Eq[A]` | `eqv(x: A, y: A): Boolean` | | |||
| `x =!= y` | not equals | | `Eq[A]` | `neqv(x: A, y: A): Boolean` | | |||
| `fa >>= f` | flatMap | | `FlatMap[F[_]]` | `flatMap(fa: F[A])(f: A => F[B]): F[B]` | | |||
| `fa >> fb` | followed by | | `FlatMap[F[_]]` | `followedBy(fa: F[A])(fb: F[B]): F[B]` | | |||
| `fa << fb` | for effect | | `FlatMap[F[_]]` | `forEffect(fa: F[A])(fb: F[B]): F[A]` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we not add them back to another place place in the doc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added them at the bottom with a deprecated notice
@@ -189,7 +189,7 @@ class FreeTests extends CatsSuite { | |||
forAll { (x: Int, y: Int) => | |||
val expr1: Free[T, Int] = Free.injectRoll[T, Test1Algebra, Int](Test1(x, Free.pure)) | |||
val expr2: Free[T, Int] = Free.injectRoll[T, Test2Algebra, Int](Test2(y, Free.pure)) | |||
val res = distr[T, Int](expr1 >> expr2) | |||
val res = distr[T, Int](expr1 >>= (_ => expr2)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why won’t *>
work here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was something odd going on with the tests so that simply replacing >> with *> did not work.
Looks good to me except for coverage. I’m on the phone now but can we exercise each of the lines to make sure there isn’t any issue that we don’t notice? Also, I wonder if this is really the last example where we have methods on the wrong type classes. Hard to catch except by audit. |
@@ -11,6 +11,18 @@ trait FlatMapSyntax extends FlatMap.ToFlatMapOps { | |||
|
|||
implicit final def catsSyntaxFlatMapIdOps[A](a: A): FlatMapIdOps[A] = | |||
new FlatMapIdOps[A](a) | |||
|
|||
implicit final def catsSyntaxFlatMapOps[F[_]: FlatMap, A](fa: F[A]): FlatMapOps[F, A] = | |||
new FlatMapOps[F, A](fa) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are untested, because of deprecation
|
||
/** Alias for [[forEffect]]. */ | ||
@inline final def <*[A, B](fa: F[A])(fb: F[B]): F[A] = | ||
forEffect(fa)(fb) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is untested because <*
and <<
were before this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3 <3 <3
👍 |
To do so, I moved
*>
and<*
fromCartesian
syntax toCartesian
type class. I also movedfollowedBy
andforEffect
toApply
. :)Should fix #1954