え?コピーされちゃう?Ocamlだよね?そのリストみた感じだと。

# let a = "abc";;
# let b = "abc";;
# a = b;;
- : bool = true (* aとbの内容比較なら真 *)
# a == b;;
- : bool = false (* aとbのポインタ比較なら偽 *)
# let x = [];;
# let y = a :: x;; (* List xにaをadd *)
val y : string list = ["abc"]
# List.hd y;;
- : string = "abc";; (* yの先頭要素は"abc" *)
# (List.hd y) = a;;
- : bool = true (* yの先頭要素とaの中身は同じ *)
# (List.hd y) = b;;
- : bool = true (* yとbも中身は同じ *)
# (List.hd y) == a;;
- : bool = true (* yとaのアドレスは同じ *)
# (List.hd y) == b;;
- : bool = false (* yとbのアドレスは別 *)

結果List x(空だけど)にaをaddした結果できた要素"abc"は
aが指している"abc"と同じで、bが指している"abc"とは別。
==演算子使って実体の場所(ようはアドレス)が同じか見てみた?

つか単一名前空間なら(List.findで探すようなものなら)、
Hashとかつかったほうが良くないですか?
OcamlにはHashtblモジュールがあったはず。