Skip to content

Instantly share code, notes, and snippets.

@pchiusano
Created November 26, 2013 22:38
Show Gist options
  • Save pchiusano/7667597 to your computer and use it in GitHub Desktop.
Save pchiusano/7667597 to your computer and use it in GitHub Desktop.
A 'balanced' version of sequencing, which realistically avoids stack overflow errors for any finite Applicative. The Applicative laws (specifically associativity and right/left identity) ensure this yields the same result as the usual right-fold based version.
trait Applicative[F[_]] {
/** 'Balanced' sequencing, to avoid SOE. */
def bsequence[A](ms: Seq[F[A]]): F[IndexedSeq[A]] = {
if (ms.isEmpty) point(Vector())
else if (ms.size == 1) ms.head.map(Vector(_))
else {
val (l,r) = ms.toIndexedSeq.splitAt(ms.length / 2)
apply2(bsequence(l), bsequence(r))(_ ++ _)
}
}
/** Also sometimes called `map2` or `lift2`. */
def apply2[A,B,C](fa: F[A], fb: F[B])(f: (A,B) => C): F[C]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment