idiom brackets

In our paper, Ross and I used Scott-brackets for idiomatic lifting. For a while, I had a cheeky typeclass hack, but it seemed like overkill, especially as it didn't nest. She now supports a notation which does the job.

the basic picture


(|f a1 .. an|)

pure f <*> a1 <*> .. <*> an

You might need some more (..) brackets, especially if your pure function is given by an ordinary application.

Infix bonus: (| blah blah +-*/ rhubarb custard |) does the same thing as (|(+-*/) (blah blah) (rhubarb custard)|).

Now you get

instance Traversable [] where
  traverse f [] = (|[]|)
  traverse f (x : xs) = (|f x : traverse f xs|)


If your Applicative is Alternative, there's a wee extension of this notation that might help. (|) denotes failure (what's ‘empty’ in Control.Applicative). Meanwhile, if you have more than one choice, you can write (| blah1 | .. | blahn |) where each blah is an application in the form described above. I've been careful to make sure that you only need an Alternative instance if you provide a number of options other than one.

I like

(| blah1
 | ..
 | blahn

like a sword with two handles and no point.

he only does it to annoy

We've got three combinators in the library, (<$), (<*), and (*>), which let you do things and ignore their values. To achieve the same effect, put this ‘noise’ in (%..%) brackets. For example, we can write a wee parser like this:

pExp :: P Char Exp
pExp =
  (| Neg    (%teq '-'%) pExp
   | (:+:)   (%teq '('%) pExp (%teq '+'%) pExp (%teq ')'%)
   | V       (tok isAlpha)

You can even write the :+: infix if you like, but it gets a bit lost.

pure but late

If you want to mix impure and pure arguments, you can stick ~ in front of the pure ones. For example, (|lookup token ~ keywordList|).

if you can't beat 'em

In monadic idioms, we sometimes compute computations. Postfixing @ computes the value of a computed computation: it just applies join to the story so far. Safe conditional expression is (|cond notADrill ~ launchMissiles ~ (|()|)) @ |).


  • Is (%..%) too heavy for the noise?
  • I want a lighter notation for traverse.
  • Better notation for monadic idioms (case, etc) would be good too.