擬似中置記法

OCamlでは、modは特別扱いで中置記法として定義されています。

# (mod);;
- : int -> int -> int = 
# 5 mod 3;;
- : int = 2

たとえばこの別名でremという関数を作りたくても、これを中置記法で定義することは出来ません。

# let (rem) x y = x mod y;;
Error: Syntax error

これは、中置演算子として定義できる文字列が、記号の特定の組み合わせ、もしくは予約された文字列、というふうに決められているからですね。
中置演算子として予約された文字列にはor,mod,land,lor,lxor,lsl,lsr,asrがあります。
(参考:公式マニュアルのinfix-opの項)

ここで、パイプ演算子を使うと、2引数関数を擬似的に中置記法で書くことができます。

# let (|>) x f = f x;;
val ( |> ) : 'a -> ('a -> 'b) -> 'b = <fun>
# let (<|) f x = f x;;
val ( <| ) : ('a -> 'b) -> 'a -> 'b = <fun>
# let rem = (mod);;
val rem : int -> int -> int = <fun>
# 5 |>rem<| 3;;
- : int = 2

中置演算にしたい関数を、|>と<|で挟み込むわけですね。パイプ演算子として読めば、データを両方から流しこむことになりますし、ひとまとめの記号として読めば中置演算子になります。ちなみに、Haskellerの友人はパイプ演算子がちょうど逆の記法になって、<|rem|>みたいな書き方をしていました。
このほうが、ひとまとめの中置演算記号っぽさは出ますね。
この場合はパイプ演算子ではなく、関数適用というイメージでしょうか。

ちなみに、演算子として定義可能な名前operator-nameは以下のように定義されています。
(参考:公式マニュアル)

operator-name ::=
  prefix-symbol | infix-op
infix-op ::=
  infix-symbol | * | = | or | & | :=
infix-symbol ::=
  ( = | < | > | @ | ^ | | | & | + | - | * | / | $ | % ) { operator-char }
prefix-symbol ::=
  ( ! | ? | ~ ) { operator-char }
operator-char ::= 
  ! | $ | % | & | * | + | - | . | / | | < | = | > | ? | @ | ^ | | | ~

既に定義されている演算子も上書き可能であったり、変数として利用することもできるので、以下のような定義も可能です。

# let (+) = (-) and (-) = (+);;
val ( + ) : int -> int -> int = <fun>
val ( - ) : int -> int -> int = <fun>
# let (<) = (>) and (>) = (<);;
val ( < ) : 'a -> 'a -> bool = <fun>
val ( > ) : 'a -> 'a -> bool = <fun>
# let (!) = 1;;
val ( ! ) : int = 1
# let (!?) = 2;;
val ( !? ) : int = 2
# (!) + (!?);;
- : int = -1
# (!) - (!?);;
- : int = 3
# (!) + (!?) < (!?);;
- : bool = false
# (!) - (!?) > (!);;
- : bool = false

……わけがわかりませんね。
使い所は難しいですが、まぁこんなことも出来るよ、ということで。