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

More efficient Alternative#separate via Foldable #2741

Closed
tkroman opened this issue Mar 2, 2019 · 0 comments
Closed

More efficient Alternative#separate via Foldable #2741

tkroman opened this issue Mar 2, 2019 · 0 comments

Comments

@tkroman
Copy link
Contributor

tkroman commented Mar 2, 2019

I was looking at the current implementation of separate and looks like at least for the list-like Fs we could benefit from a single-pass implementation (well, not for lists since list's combine is ++, but for some structures which have more efficient combine implementations :)).

Compare current implementation:

def separate[G[_, _], A, B](fgab: F[G[A, B]])(implicit FM: Monad[F], G: Bifoldable[G]): (F[A], F[B]) = {
  val as = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(pure, _ => empty[A])(algebra[A]))
  val bs = FM.flatMap(fgab)(gab => G.bifoldMap(gab)(_ => empty[B], pure)(algebra[B]))
  (as, bs)
}

to the one proposed:

def separateFoldable[G[_, _], A, B](fgab: F[G[A, B]])(implicit
                                                      G: Bifoldable[G],
                                                      FF: Foldable[F]): (F[A], F[B]) = {
  FF.foldLeft(fgab, (empty[A], empty[B])) { case (mamb, gab) =>
    G.bifoldLeft(gab, mamb)(
      (t, a) => (combineK(t._1, pure(a)), t._2),
      (t, b) => (t._1, combineK(t._2, pure(b)))
    )
  }
}

In any case, for foldables this would at least reduce the number of empty allocations etc etc.

Note: I'm obviously not suggesting replacing the current one which is strictly more generic, but adding an alternative (pun not intended) implementation alongside existing one.

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

No branches or pull requests

1 participant