choice combines a Boolean computation with two parallel computations. It runs the condition first, waits for its result, then runs either the true branch or the false branch. section 7.4
A blocking implementation
def choice[A](cond: Par[Boolean])(t: Par[A], f: Par[A]): Par[A] = es => if cond.run(es).get then t(es) else f(es) The implementation makes the sequencing explicit: obtain the Boolean result, select one computation, and run that computation in the same environment. section 7.4
The two-branch interface is a special case of increasingly general selection patterns:
- choiceN selects from a List[Par[A]] using an integer result. section 7.4
- choiceMap selects from a Map[K, Par[V]] using a computed key. section 7.9
- chooser removes the container-specific interface by accepting a function from the computed result to the selected computation. section 7.4
def choice[A](cond: Par[Boolean])(t: Par[A], f: Par[A]): Par[A] = cond.chooser(b => if b then t else f)
View choice expressed through chooser: the Boolean result directly selects the true or false computation. section 7.9
