# The Conditional Choice Operator

by Nicolas Wu

Posted on 1 August 2011

Tags: Haskell

A recent reddit post asking for a library of conditional one-liners and combinators reminded me of one of my favourite operators: the conditional choice. Most programmers are used to the so-called McCarthy conditional:

`if p then x else y`

An alternative way of viewing this is as a ternary operator:

`<| p |> y x `

This operator is known as the *conditional choice*, but I’m told that it was
introduced by Tony Hoare, so maybe naming it the Hoare conditional would make
more sense (it makes an appearance in Hoare’s work on
Communicating Sequential Processes and
Unifying Theories of Programming, but I haven’t found any references
to its original introduction).

## Laws

Rendering conditonals as ternary operators makes it clear that there are a number of nice properties that hold true:

Idempotency

< x <| p |> x == x

Left-Identity

< x <| True |> y == x

Right-Identity

< x <| False |> y == y

Left-Distributivity

< x <| p |> (y <| q |> z) == (x <| p |> y) <| q |> (x <| p |> z)

Right-Distributivity

< (x <| p |> y) <| q |> z == (x <| q |> z) <| p |> (y <| q |> z)

Symmetry

< x <| p |> y == y <| not p |> x

Conjunction-Associativity

< (x <| p |> y) <| q |> z == x <| p && q |> (y <| q |> z)

Disjunction-Associativity

< x <| p |> (y <| q |> z) == (x <| p |> y) <| p || q |> z

Conjunction-Collapse

< x <| p |> (y <| p && q |> z) == x <| p |> z

Disjunction-Collapse

< (x <| p || q |> y) <| q |> z == x <| q |> z

Abiding (Interchange)

< x # y <| p |> v # w == (x <| p |> v) # (y <| p |> w)

These laws are easily proved by considering the cases where `p`

and `q`

are
`True`

and `False`

.

## Implementation

In Haskell, implementing this operator is quite simple.
First we’ll define the right bracket, which takes a predicate
and a value `x`

, and returns `Nothing`

if the predicate is `True`

,
and returns `Just x`

when it is `False`

:

```
(|>) :: Bool -> a -> Maybe a
True |> _ = Nothing
False |> y = Just y
```

The left bracket is equivalent to `fromMaybe`

, where the resulting value
from the application of the right bracket (which evaluates the predicate) is
consumed. If the result was `Nothing`

, then we use the value `x`

, otherwise
we have `Just y`

, and return `y`

as the result.

```
(<|) :: a -> Maybe a -> a
<| Nothing = x
x <| Just y = y _
```

Finally we give the operators low infixity precedence, and make them right associative:

```
infixr 0 <|
infixr 0 |>
```

Defining the operator this way makes the ternary operator right associative, so that:

`<| p |> y <| q |> z == x <| p |> (y <| q |> z) x `

Right associativity here is useful so that reading from left to right, the result is the expression to the left of the first predicate that is true.