λx. x K S K @はてな

このブログ内に記載された文章およびコードの著作権は,すべて Keisuke Nakano に帰属します.

#004 中置演算子化

Haskell の場合,任意の関数 f に対し, `f` のように `(バッククオート)で囲むことにより中置演算子(infix operator)として用いることができる. 一方,OCaml でユーザが定義できる中置演算子は一部の記号に限定されている.

以下では,OCaml で任意の関数を中置演算子にしてしまう狡い(?)方法を紹介する. まず,次のような中置演算子を定義する.

let (<|) x y = y x and (|>) x y = x y

この <||> を使うことにより, Haskell のように簡単に中置演算子化することができる. たとえば,二引数の最小値をとる関数 min に対して, 3 <|min|> 4 と記述することができる. 後ろの |> は実際何もしてないのだが, 演算子の優先順位の都合上 (3 <| min) 4 などと書く必要があるため, あまり中置演算子っぽくない記述になってしまう.

なお,このように作られた中置演算子は左結合となるため, 3 <|min|> 4 <|max|> 5 の結果は,5 となる. 右結合となる中置演算子を作りたければ,

let (@^) x y = y x and (^@) x y z = x z y
としてもよい. これにより, 3 @^min^@ 4 @^max^@ 5 の結果は,3 となる. また,中置演算子 <|...|>@^...^@ とでは, 後者の方が優先順位が高い. 優先順位の高い左結合演算子を作りたければ,
let ( -* ) x y = y x and ( *- ) x y = x y
とでもすればよい.ただ,こうまでして(優先順位に敏感な)中置演算子を作る必要があるかは甚だ謎である.