in algebird-core/src/main/scala/com/twitter/algebird/Eventually.scala [77:114]
override def sumOption(iter: TraversableOnce[Either[E, O]]): Option[Either[E, O]] = {
def toEventualBuffer[R](buffer: Buffer[O], e: E): Left[Buffer[E], R] = {
val newBuffer = Buffer[E]()
Semigroup.sumOption(buffer).foreach(sum => newBuffer += convert(sum))
newBuffer += e
Left(newBuffer)
}
iter.iterator.foldLeft[Either[Buffer[E], Buffer[O]]](Right(Buffer[O]())) {
case (buffer @ Left(be), v) =>
// turns the list of either into an either of lists
checkSize(be)
v match {
case Left(ve) => be += ve
case Right(vo) => be += convert(vo)
}
buffer // left stays left we just add to the buffer and convert if needed
case (buffer @ Right(bo), v) =>
checkSize(bo)
v match {
// one Left eventual value => the right list needs to be converted
case Left(ve) => toEventualBuffer(bo, ve)
// otherwise stays Right, just add to the buffer
case Right(vo) =>
bo += vo
buffer
}
} match { // finally apply sumOption accordingly
case Left(be) => Semigroup.sumOption(be).map(left(_))
case Right(bo) =>
if (bo.lengthCompare(1) <= 0) bo.headOption.map(Right(_))
else
Semigroup
.sumOption(bo)
.map(conditionallyConvert(_)) // and optionally convert
}
}