Skip to content
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 Foldable extension collectFirstSomeM #2366

Merged

Conversation

catostrophe
Copy link
Contributor

Monadic version of collectFirstSome. Implemented as a syntax extension for binary compatibility.

@codecov-io
Copy link

codecov-io commented Aug 5, 2018

Codecov Report

Merging #2366 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2366      +/-   ##
==========================================
+ Coverage   95.01%   95.01%   +<.01%     
==========================================
  Files         349      349              
  Lines        5998     6003       +5     
  Branches      222      222              
==========================================
+ Hits         5699     5704       +5     
  Misses        299      299
Impacted Files Coverage Δ
core/src/main/scala/cats/syntax/foldable.scala 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9aa77a9...8b8024a. Read the comment docs.

* }}}
*/
def collectFirstSomeM[G[_], B](f: A => G[Option[B]])(implicit F: Foldable[F], G: Monad[G]): G[Option[B]] =
F.foldRight(fa, Eval.now(OptionT.none[G, B]))((a, lb) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to implement this without OptionT? I think there's some overhead involved when wrapping values in monad transformers, and this is library code so it shouldn't be that problematic to use the wrapped values directly

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, it would. Will do if you think it's worth it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah let's try to do it as efficiently as possible :)

def collectFirstSomeM[G[_], B](f: A => G[Option[B]])(implicit F: Foldable[F], G: Monad[G]): G[Option[B]] =
F.foldRight(fa, Eval.now(G.pure(Option.empty[B])))((a, lb) =>
Eval.now(G.flatMap(f(a)) {
case s @ Some(_) => G.pure(s)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also match on None first and then add case s - we'll avoid an instance check and cast, so it could be good for performance. Not sure if the difference is significant though, we'd need to benchmark. Feel free to ignore this comment ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Let me perform some jmh benchmarks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kubukoz JMH proved you right :)

F.foldRight(fa, Eval.now(OptionT.none[G, B]))((a, lb) =>
Eval.now(OptionT(f(a)).orElse(lb.value))
).value.value
F.foldRight(fa, Eval.now(G.pure(Option.empty[B])))((a, lb) =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@catostrophe
Copy link
Contributor Author

What's the preferred way to restart a failed Travis build if no file changes needed? push force?

@kubukoz
Copy link
Member

kubukoz commented Aug 11, 2018 via email

Copy link
Contributor

@kailuowang kailuowang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@kailuowang kailuowang merged commit f2bc669 into typelevel:master Aug 15, 2018
@kailuowang kailuowang added this to the 1.3 milestone Aug 16, 2018
catostrophe added a commit to catostrophe/cats that referenced this pull request Sep 15, 2018
* Add Foldable extension collectFirstSomeM

* Implement without OptionT

* Optimize pattern matching

* Empty commit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants