Does!= Имеет смысл в OCaml?
Кажется, это сравнение эквивалентности для некоторых типов, но не строк.
# 3 != 3;;
- : bool = false
# 3 != 2;;
- : bool = true
Это как и ожидалось.
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
Почему "odp" != "odp"
оценивается до true
? Что это на самом деле делает? Не следует ли генерировать ошибку типа?
Ответы
Ответ 1
вы испытали разницу между структурным и физическим равенством.
<>
соответствует =
(структурное равенство), поскольку !=
имеет значение ==
(физическое равенство)
"odg" = "odg" (* true *)
"odg" == "odg" (* false *)
является ложным, потому что каждый экземпляр создается в разных ячейках памяти, делая:
let v = "odg"
v == v (* true *)
v = v (* true *)
В большинстве случаев вы захотите использовать =
и <>
.
изменить, когда структурное и физическое равенство эквивалентны:
Вы можете использовать функцию what_is_it и узнать все типы, которые были бы одинаковыми как структурно, так и физически. Как упоминалось в комментариях ниже, и в связанной статье, это свойство будут иметь символы, целые числа, единица, пустой список и некоторые экземпляры типов вариантов.
Ответ 2
Противоположным для оператора !=
является оператор ==
, а не =
.
# "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
Ответ 3
Краткое описание ==
и !=
в 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 "логический или" оператор "ленивый",
let equal t1 t1 =
(t1 == t2) ||
match ...
Ответ 4
Они похожи на двух "Томов" в вашем классе! Потому что:
В этом случае "odp" = "odp"
потому что это строки TWOstrong > с SAME VALUE!!
Так что они не ==
, потому что они TWOstrong > хранятся в разных строках разные (Память) местоположение
Они =
, потому что они имеют идентичное строковое значение.
Еще один шаг глубже, "odp" - анонимная переменная. И две анонимные переменные приводят к этим строкам Два.
Для вашего удобства:
# "odp" = "odp";;
- : bool = true
# "odp" != "odp";;
- : bool = true
# "odp" <> "odp";;
- : bool = false
Ответ 5
ints - единственный тип, где физическое и структурное равенство одинаковы, поскольку ints - единственный тип, который распакован