blog

# The application operator in Standard ML

# April 22, 2012

In the previous post I introduced the `\$` operator to OCaml using two different approaches:

1. Renaming the operator to `**\$` or `@\$` in order to achieve the necessary associativity.
2. Leveraging Camlp4 to provide a syntax extension.

In the comments section1, variants of these operators were provided that mirror Haskell’s relative precedence of application and composition.

As a postscript, I thought it might be interesting to look at the implementation of `\$` in Standard ML. Here it is in the SML/NJ toplevel,

``````Standard ML of New Jersey v110.74 [built: Wed Apr 11 13:33:07 2012]
- infixr 0 \$;
infixr \$
- fun (f \$ x) = f x;
val \$ = fn : ('a -> 'b) * 'a -> 'b``````

Of note:

• Standard ML lets us specify the associativity of newly defined operators explicitly (using the `infix*` fixity directives) whereas OCaml follows an operator naming convention.
• As such, we have no need to fall back on syntax extensions here; `\$` is a valid name for a right associative operator.

To replicate the target example of the previous post we’ll need to define a few utilities,

``````- fun succ x = x + 1;
val succ = fn : int -> int
- val sum = foldl op+ 0;
val sum = fn : int list -> int
- fun printLn str = print \$ str ^ "\n";
val printLn = fn : string -> unit``````

Note that `printLn` is defined using `\$`; the standard approach would be `fun printLn str = print (str ^ "\n")`.

With these definitions in place, we can employ `\$` to print the desired result:

``````- printLn \$ Int.toString \$ succ \$ sum [1, 2, 3];
7
val it = () : unit``````

Finally, since `\$` was defined with a precedence level of `0`, it interacts correctly with SML’s composition operator, `o`, which has a precedence of `3` (as per the Standard):

``````- printLn o Int.toString \$ succ \$ sum [1, 2, 3];
7
val it = () : unit``````

1. See the closing Update.