Имеет ли! = Значение в OCaml? - PullRequest
61 голосов
/ 11 сентября 2009

Кажется, это сравнение эквивалентности для некоторых типов, но не для строк.

# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true

Это как и ожидалось.

# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false

Почему "odp" != "odp" оценивается как true? Что он на самом деле делает? Разве это не должно генерировать ошибку типа?

Ответы [ 5 ]

89 голосов
/ 11 сентября 2009

вы испытали разницу между структурным и физическим равенством.

<> - = (структурное равенство), а != - == (физическое равенство)

"odg" = "odg"  (* true  *)
"odg" == "odg" (* false *)

ложно, потому что каждый экземпляр создается в разных местах памяти, выполняя:

let v = "odg"
v == v (* true *)
v = v  (* true *)

Большую часть времени вы захотите использовать = и <>.

редактировать, когда структурное и физическое равенство эквивалентны :

Вы можете использовать функцию what_is_it и найти все типы, которые были бы одинаковы как по структуре, так и по физике. Как упоминалось в комментариях ниже и в связанной статье, это свойство имеют символы, целые числа, единицы измерения, пустой список и некоторые экземпляры типов вариантов.

16 голосов
/ 11 сентября 2009

Оператор != противоположен оператору ==, а не =.

# "a" != "a" ;;
- : bool = true
# "a" == "a" ;;
- : bool = false

Оператор == является "физическим равенством". Когда вы набираете "a" == "a", вы сравниваете два разных экземпляра строк, которые выглядят одинаково, поэтому оператор возвращает false. Хотя наличие одного экземпляра возвращает значение true:

# let str = "a"
  in str == str ;;
- : bool = true
# let str = "a"
  in str != str ;;
- : bool = false
12 голосов
/ 13 сентября 2009

Краткое объяснение == и != в OCaml в дополнение ко всем правильным ответам, которые уже были предоставлены:

1 / == и != раскрывают детали реализации, о которых вы действительно не хотите знать. Пример:

# let x = Some [] ;;
val x : 'a list option = Some []
# let t = Array.create 1 x ;;
val t : '_a list option array = [|Some []|]
# x == t.(0) ;;
- : bool = true

Пока все хорошо: x и t.(0) физически равны, потому что t.(0) содержит указатель на тот же блок, на который указывает x. Это то, что требует базовых знаний о реализации. НО:

# let x = 1.125 ;;
val x : float = 1.125
# let t = Array.create 1 x ;;
val t : float array = [|1.125|]
# x == t.(0) ;;
- : bool = false

То, что вы видите здесь, является результатами полезной в других отношениях оптимизации с использованием поплавков.

2 / С другой стороны, есть безопасный способ использования ==, и это быстрый, но неполный способ проверки на структурное равенство.

Если вы пишете функцию равенства на бинарных деревьях

let equal t1 t2 =
  match ...

проверка t1 и t2 на физическое равенство - это быстрый способ обнаружить, что они явно структурно равны, даже не требуя их повторения и чтения. То есть:

let equal t1 t2 =
  if t1 == t2
  then true
  else 
    match ...

И если учесть, что в OCaml оператор «boolean or» является «lazy»,

let equal t1 t1 =
  (t1 == t2) ||
  match ...
2 голосов
/ 25 июня 2013

Они как два "Тома" в вашем классе! Потому что:

В этом случае "odp" = "odp" потому что они ДВА строки с ЖЕ ЗНАЧЕНИЕ !!

То есть они не ==, потому что они TWO хранят разные строки в разные (память) местоположение

Это =, потому что они имеют идентичное строковое значение .

Еще один шаг глубже, "odp" - анонимная переменная. И две анонимные переменные приводят к этим двум строкам.

Для вашего удобства:

# "odp" = "odp";; 
- : bool = true 
# "odp" != "odp";; 
- : bool = true 
# "odp" <> "odp";; 
- : bool = false
0 голосов
/ 11 сентября 2009

целочисленные значения являются единственным типом, где физическое и структурное равенство одинаковы, потому что целочисленные значения являются единственным типом, который распакован

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...