in src/main/scala/com/twitter/stitch/Arrow.scala [2697:2724]
def join[A, B, C, D](a1: Arrow[A, B], a2: Arrow[A, C], a3: Arrow[A, D]): Arrow[A, (B, C, D)] =
joinMap(a1, a2, a3)((_, _, _))
/**
* `Arrow.joinMap(a1, a2, a3)(k)` is equivalent to
* `Arrow.join(a1, a2, a3).map(k.tupled)`,
* but avoids allocating an intermediate tuple.
*/
def joinMap[A, B, C, D, Z](
a1: Arrow[A, B],
a2: Arrow[A, C],
a3: Arrow[A, D]
)(
k: (B, C, D) => Z
): Arrow[A, Z] =
(a1, a2, a3) match {
case (Const(Throw(e)), _, _) => exception(e)
case (_, Const(Throw(e)), _) => exception(e)
case (_, _, Const(Throw(e))) => exception(e)
case (Const(Return(v1)), _, _) =>
joinMap(a2, a3) { (v2, v3) => k(v1, v2, v3) }
case (_, Const(Return(v2)), _) =>
joinMap(a1, a3) { (v1, v3) => k(v1, v2, v3) }
case (_, _, Const(Return(v3))) =>
joinMap(a1, a2) { (v1, v2) => k(v1, v2, v3) }
case _ =>
JoinMap3(a1, a2, a3, k)
}