2016-06-12 7 views
3

В Caml оператор == проверяет физическое равенство между двумя значениями одного и того же типа. Его можно использовать, в частности, для сравнения функций таким образом.Тест на физическое равенство для функций в Caml

Надо, например

# print_string == print_string;; 
- : bool = true 

, но, как ни удивительно,

# (==) == (==);; 
- : bool = false 

Это выражение должно быть оценено в true.

Можете ли вы объяснить это поведение?

+5

'(==)' не существует как замыкание, готовое быть, скажем, переданным функции высокого порядка. Его приложения создаются непосредственно в форме. Закрытие выделяется каждый раз, когда нужно, и два таких закрытия выделяются при разных адресах при записи '(==) == (==)'. Если вам нужны аналогичные свойства 'print_string', с текущими реализациями OCaml, дайте имя одному закрытию, которое вы заставите себя использовать везде:' let phys_equal x y = x == y ;; '. Это также может быть более эффективным с точки зрения памяти, чем распределение замыканий для unapplied '(==)' каждый раз. –

ответ

5

Поведение == определяется в Pervasives модуле:

e1 == e2 тесты для физического равенства e1 и e2. В отношении изменяемых типов, таких как ссылки, массивы, последовательности байтов, записи с изменяемыми полями и объектами с изменяемыми переменными экземпляра, e1 == e2 является истинным тогда и только тогда, когда физическая модификация e1 также влияет на e2. По непеременным типам поведение (==) зависит от реализации; Однако, это гарантирует, что e1 == е2 означает сравнить e1 e2 = 0

Поскольку функции не являются изменяемыми, единственной гарантией является то, что, если они считаются равными с == они также будут сравнивать равные с compare. Поскольку функции не гарантируются быть сопоставимыми с compare, это по существу означает, что == вообще не является полезным для сравнения функций.

# compare (==) (==);; 
Exception: Invalid_argument "equal: functional value". 

== Если возвращает false для неизменных ценностей, нет никаких гарантий на всех. Это означает, что == может в любое время вернуть false для любых неизменяемых значений. Поэтому в вашем втором примере неправильно возвращать false.