-
-
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
Add iterateWhileM and iterateUntilM #1809
Conversation
looks great! Thanks! 👍 pending build pass. |
Codecov Report
@@ Coverage Diff @@
## master #1809 +/- ##
==========================================
+ Coverage 94.96% 94.97% +<.01%
==========================================
Files 241 241
Lines 4193 4195 +2
Branches 117 109 -8
==========================================
+ Hits 3982 3984 +2
Misses 211 211
Continue to review full report at Codecov.
|
Just wondering, these Edit: I missed that in the |
@peterneyens It's a common idiom in Haskell where Simple games are a frequent example. So the main loop becomes something like def initialWorld: World = ??? // initial world state
def stepWorld(old): IO[World] = getUserInput >>= updateWorld(old) >>! refreshUI
def keepRunning(current): Boolean = isPlayerAlive(current)
def loop: IO[World] = initialWorld.iterateWhileM(stepWorld)(keepRunning) This example could all be rewritten using def loop = stepWorld.iterateWhile(keepRunning).run(initialWorld) would work. But pulling in |
I think of
|
I agree that some less trivial tests/examples would be nice. |
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 looks fine to me, but I agree it would be nice to see a test with something less trivial, like Eval
maybe.
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 great, in my opinion, but I'd also like to see a more meaty monad in the tests. I'd like to see State or Reader for instance.
@@ -74,4 +74,28 @@ class MonadTest extends CatsSuite { | |||
result should ===(50000) | |||
} | |||
|
|||
test("iterateWhileM") { | |||
forAll(Gen.posNum[Int]) { (max: Int) => |
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.
might this not run a super long time? any reason why max
shouldn't be something from like: Gen.choose(0, 500000)
?
core/src/main/scala/cats/Monad.scala
Outdated
* Apply a monadic function iteratively until its result fails | ||
* to satisfy the given predicate and return that result. | ||
*/ | ||
def iterateWhileM[A](init: A)(f: A => F[A])(p: A => Boolean): 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.
no need for the outer { }
here.
core/src/main/scala/cats/Monad.scala
Outdated
* Apply a monadic function iteratively until its result satisfies | ||
* the given predicate and return that result. | ||
*/ | ||
def iterateUntilM[A](init: A)(f: A => F[A])(p: A => Boolean): 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.
no need for the outer { }
5742379
to
3ae823b
Compare
core/src/main/scala/cats/Monad.scala
Outdated
if (p(a)) | ||
map(f(a))(_.asLeft[A]) | ||
else | ||
pure(a.asRight[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.
Can we replace the asLeft
and asRight
with just Left(..)
and Right(..)
(in whileM
as well) ?
bcfd5e6
to
075ae1f
Compare
LGTM, @peterneyens @johnynek looks like that the comments were addressed. any other feedback? |
I've left the I'm also working on some additions to the |
I love the doc ideas, they sound awesome. I'd say we can have them in a separate PR so that we can have the binary breaking change merged in asap. |
075ae1f
to
60d8e5a
Compare
Looks good to me. 👍 |
since all feedback seems addressed and I am going to merge with 3 sign-offs. |
* Limit runtime of monad loop tests * Do not use Either syntax in monad loops * Add iterateWhileM and iterateUntilM * Implement iterateWhile in terms of iterateWhileM
iterateWhileM
anditerateUntilM
to complement the existingiterateWhile
anditerateUntil
methods.iterateWhile
anditerateUntil
in terms of the newiterateWhileM
anditerateUntilM
.