[Haskell-cafe] if-then-else as rebindable syntax (was Re: Why does Haskell have the if-then-else syntax?)

Niklas Broberg niklas.broberg at gmail.com
Fri Jul 28 06:57:03 EDT 2006


(Appologies to Malcolm for multiple copies. Say after me, Reply All!)

On 7/28/06, Malcolm Wallace <Malcolm.Wallace at cs.york.ac.uk> wrote:
> "David House" <dmhouse at gmail.com> wrote:
>
> > > Or perhaps (?:) or something like that,
> >
> > This has come up a few times on #haskell, and the consensus is that a
> > tertiary (?:) operator isn't possible because of the deep specialness
> > of (:). However, you can simulate it pretty well:
> >
> > infixr 1 ?
> > (?) :: Bool -> (a, a) -> a
> > True  ? (t, _) = t
> > False ? (_, t) = t
> >
> > length "hello" > 4 ? ("yes it is!", "afraid not")
>
> HaXml has a lifted version of C's tertiary operator, which matches C's
> syntax even more closely:
>
>     data ThenElse a = a :> a
>     infixr 3 ?>, :>
>
>     (?>) :: (a->Bool) -> ThenElse (a->b) -> (a->b)
>     p ?> (f :> g) = \c-> if p c then f c else g c
>
> You can drop it back down to the term level easily enough:
>
>     (?>) :: Bool -> ThenElse a -> a
>     p ?> (t :> e) = if p then t else e
>
> Because the operators are right associative, you don't need parens when
> you use it:
>
>   length "hello" == 4  ?>  "yes it is!"  :>  "afraid not"

I've used this trick as well with a ThenElse data constructor, but
that's just for aesthetical reasons, wanting the : first. You could
just as easily say e.g.

 (?) :: Bool -> (a,a) -> a
 (?) p = if p then fst else snd

 (<:>) :: a -> a -> (a,a)
 a <:> b = (a,b)

and use it like

 length "hello" == 4  ?  "yup"  <:>  "nope"

The benefit over Malcolm's version is that the (?) operator becomes
useful in its own right, like David's version.

/Niklas


More information about the Haskell-Cafe mailing list