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 Iterant.foldRightL #402

Merged
merged 6 commits into from Aug 7, 2017

Conversation

Projects
None yet
1 participant
@alexandru
Member

alexandru commented Aug 6, 2017

Right-associative fold, i.e. foldr from Haskell's Foldable.

Examples used in tests:

def exists[F[_], A](fa: Iterant[F, A], p: A => Boolean)(implicit F: Sync[F]): F[Boolean] =
  fa.foldRightL(F.pure(false)) { (e, next, stop) =>
    if (p(e)) stop >> F.pure(true) else next
  }

def forall[F[_], A](fa: Iterant[F, A], p: A => Boolean)(implicit F: Sync[F]): F[Boolean] =
  ref.foldRightL(F.pure(true)) { (e, next, stop) =>
    if (!p(e)) stop >> F.pure(false) else next
  }

def concat[F[_], A](lh: Iterant[F, A], rh: Iterant[F, A])
  (implicit F: Sync[F]): Iterant[F, A] = {

  Iterant.suspend[F, A] {
    lh.foldRightL(F.pure(rh)) { (a, rest, stop) =>
      // This is a lazy "prepend" that takes `stop` into account
      F.pure(Iterant.nextS(a, rest, stop))
    }
  }
}

Note: the function receives a third parameter called stop, which should be chained in case the processing is short-circuited, i.e. in case the second parameter (that represents the lazy result from recursively combining the rest of the list) isn't chained.

It's the user's responsibility to correctly chain stop, as the implementation cannot do it automatically, as it cannot detect short-circuiting. This creates unsafety, compared with all other operators, however it's either this, or not having a foldRight operator at all.

Plus for many use-cases a safer foldWhileLeft operator is available, as introduced in PR #404 and mentioned in ScalaDoc.

@codecov

This comment has been minimized.

codecov bot commented Aug 6, 2017

Codecov Report

Merging #402 into master will decrease coverage by 0.02%.
The diff coverage is 92.3%.

@@            Coverage Diff             @@
##           master     #402      +/-   ##
==========================================
- Coverage   88.25%   88.23%   -0.03%     
==========================================
  Files         339      340       +1     
  Lines        9087     9100      +13     
  Branches     1181     1188       +7     
==========================================
+ Hits         8020     8029       +9     
- Misses       1067     1071       +4

@alexandru alexandru merged commit b0bd182 into monix:master Aug 7, 2017

1 check was pending

continuous-integration/travis-ci/pr The Travis CI build is in progress
Details

@alexandru alexandru added this to the 3.0.0 milestone Jan 21, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment