プログラミングと絵と音楽

コンピューター科学を専攻し、絵と音楽を趣味とするエンジニアのブログです。

OCaml の比較で間違っていた話

OCaml の処理系の実装を大学の課題で取り組んだことがあって、そのときは let多相の実装まで取り組めなかったので、改めてやってみることにしました。
let多相というのは、例えば引数を一つ受け取って同じ値を返す関数 id を定義すると、

# let id x = x;;
val id : 'a -> 'a

となり、

# id 1;;
- : int = 1
# id true;;
- : bool = true

のように、様々な型(例の場合、 id は int -> int と bool -> bool の型を持つ)に対して操作を施せるものです。
let多相の実装と直接関係する話ではありませんが、 OCaml で比較を行う際に間違いをおかしてしまっていたので、それを記しておきます。
OCaml において等値かどうかを判断する場合は = で行えます。 Haskell の deriving show と同様に、コンストラクタが同じ場合は中味を見るというようになっている(と推測される)ため、

# Some 1 = Some 1
- : bool = true

となります。ですが、同じ感覚で等値の否定として != という演算子を用いると、

# Some 1 != Some 1
- : bool = true

となり、期待した結果と違う結果が得られます。
不思議に思って次のように演算子を確かめてみると、

# (!=);;
- : 'a -> 'a -> bool = <fun>
# (!==);;
Error: Unbound value !==
Hint: Did you mean != or ==?

と出てきたので理由がわかりました。 == はオブジェクトが同じものを参照しているかどうかを判断する演算子で、 != は == の対ではないかという推測ができます。
どうやら a = b の否定をする場合は not (a = b) とすべきのようですね。