web-dev-qa-db-fra.com

Est-ce que! = A un sens dans OCaml?

Cela semble être une comparaison d'équivalence pour certains types, mais pas pour les chaînes.

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

C'est comme prévu.

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

Pourquoi "odp" != "odp" évaluer en true? Que fait-il réellement? Cela ne devrait-il pas générer une erreur de type?

61
Nick Heiner

vous avez fait la différence entre l'égalité structurelle et l'égalité physique.

<> est à = (égalité structurelle) comme != est à == (égalité physique)

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

est faux car chacun est instancié dans différents emplacements de mémoire, en faisant:

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

La plupart du temps, vous voudrez utiliser = et <>.

modifier quand l'égalité structurelle et physique sont équivalentes :

Vous pouvez utiliser la fonction what_is_it et découvrir tous les types qui seraient égaux à la fois structurellement et physiquement. Comme mentionné dans les commentaires ci-dessous, et dans l'article lié, les caractères, les entiers, l'unité, la liste vide et certaines instances de types de variantes auront cette propriété.

91
nlucaroni

Le contraire pour != L'opérateur est ==, pas l'opérateur = une.

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

L'opérateur == est une "égalité physique". Lorsque vous tapez "a" == "a", vous comparez deux instances différentes de chaînes qui se ressemblent, donc l'opérateur retourne false. Tout en ayant une instance, cela retourne vrai:

# let str = "a"
  in str == str ;;
- : bool = true
# let str = "a"
  in str != str ;;
- : bool = false
16
P Shved

Une explication rapide sur == Et != Dans OCaml en plus de toutes les bonnes réponses qui ont déjà été fournies:

1/== Et != Exposent des détails d'implémentation que vous ne voulez vraiment pas connaître. Exemple:

# 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

Jusqu'à présent, tout va bien: x et t.(0) sont physiquement égaux car t.(0) contient un pointeur vers le même bloc que x pointe. C'est ce que dicte la connaissance de base de l'implémentation. MAIS:

# 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

Ce que vous voyez ici sont les résultats d'une optimisation autrement utile impliquant des flottants.

2/D'un autre côté, il existe un moyen sûr d'utiliser ==, Et c'est un moyen rapide mais incomplet de vérifier l'égalité structurelle.

Si vous écrivez une fonction d'égalité sur des arbres binaires

let equal t1 t2 =
  match ...

vérifier t1 et t2 pour une égalité physique est un moyen rapide de détecter qu'ils sont évidemment structurellement égaux, sans même avoir à les consulter et à les lire. C'est:

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

Et si vous gardez à l'esprit que dans OCaml, l'opérateur "booléen ou" est "paresseux",

let equal t1 t1 =
  (t1 == t2) ||
  match ...
12
Pascal Cuoq

Ils sont comme deux "Tom" dans ta classe! Car:

Dans ce cas, "odp" = "odp" car ce sont DEUX chaînes avec MÊME VALEUR !!

Ils ne sont donc pas == car ils sont DEUX chaînes différentes stockées dans différent (mémoire) emplacement

Elles sont = car ils ont la valeur de chaîne identique.

Un peu plus loin, "odp" est une variable anonyme. Et deux variables anonymes mènent à cela Deux chaînes.

Pour ta convenance:

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

les entiers sont le seul type où l'égalité physique et structurelle sont identiques, car les entiers sont le seul type qui n'est pas en boîte

0
newacct